FreeBSD ptrace RFI and vm_map PROT_EXEC bypass (uchambuzi wa kesi wa PS5)

Reading time: 8 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Muhtasari

Ukurasa huu unaweka kumbukumbu mbinu ya vitendo ya kuingiza processo/ELF ya usermode kwenye PlayStation 5 (PS5), ambayo inatokana na FreeBSD. Mbinu hii inafaa pia kwa derivatives za FreeBSD wakati tayari una kernel read/write (R/W) primitives. Kwa kiwango cha juu:

  • Badilisha credentials za mchakato wa sasa (ucred) ili kumpa mamlaka ya debugger, kuruhusu ptrace/mdbg kwenye michakato ya mtumiaji yoyote.
  • Tafuta michakato lengwa kwa kutembea kupitia orodha ya kernel allproc.
  • Bypass vikwazo vya PROT_EXEC kwa kubadilisha vm_map_entry.protection |= PROT_EXEC kwenye vm_map ya lengwa kupitia uandishi wa data za kernel.
  • Tumia ptrace kufanya Remote Function Invocation (RFI): simamisha thread, weka rejista ili kuita functions yoyote ndani ya lengwa, endesha tena, kusanya return values, na rudisha state.
  • Ramisha na endesha ELF payloads yoyote ndani ya lengwa kwa kutumia in-process ELF loader, kisha anzisha thread maalum inayotekeleza payload yako na kusababisha breakpoint ili kutenganishwa safi.

Vidhibiti vya hypervisor vya PS5 vinavyostahili kutajwa (kwa muktadha wa mbinu hii):

  • XOM (execute-only .text) inazuia kusoma/kuandika kernel .text.
  • Clearing CR0.WP au disabling CR4.SMEP husababisha hypervisor vmexit (crash). Uandishi wa kernel wa data pekee ndio inawezekana.
  • mmap ya userland imezuiwa kwa PROT_READ|PROT_WRITE kwa default. Kumpa PROT_EXEC lazima kufanyike kwa kuhariri vm_map entries katika memory ya kernel.

Mbinu hii ni post-exploitation: inadhani kuwa una kernel R/W primitives kutoka kwenye exploit chain. Public payloads zinaonyesha hili hadi firmware 10.01 wakati wa kuandika.

Kernel data-only primitives

Process discovery via allproc

FreeBSD inaweka orodha iliyounganishwa mara mbili ya michakato katika kernel .data kwenye allproc. Ukiwa na kernel read primitive, itezesha ili kupata majina ya michakato na PIDs:

c
struct proc* find_proc_by_name(const char* proc_name){
uint64_t next = 0;
kernel_copyout(KERNEL_ADDRESS_ALLPROC, &next, sizeof(uint64_t)); // list head
struct proc* proc = malloc(sizeof(struct proc));
do{
kernel_copyout(next, (void*)proc, sizeof(struct proc));       // read entry
if (!strcmp(proc->p_comm, proc_name)) return proc;
kernel_copyout(next, &next, sizeof(uint64_t));                // advance next
} while (next);
free(proc);
return NULL;
}

void list_all_proc_and_pid(){
uint64_t next = 0;
kernel_copyout(KERNEL_ADDRESS_ALLPROC, &next, sizeof(uint64_t));
struct proc* proc = malloc(sizeof(struct proc));
do{
kernel_copyout(next, (void*)proc, sizeof(struct proc));
printf("%s - %d\n", proc->p_comm, proc->pid);
kernel_copyout(next, &next, sizeof(uint64_t));
} while (next);
free(proc);
}

Vidokezo:

  • KERNEL_ADDRESS_ALLPROC inategemea firmware.
  • p_comm ni jina la ukubwa thabiti; fikiria utambuzi kupitia pid->proc ikiwa inahitajika.

Inua kredensiali kwa debugging (ucred)

Kwenye PS5, struct ucred ina shamba la Authority ID linaloweza kupatikana kupitia proc->p_ucred. Kuandika Authority ID ya debugger kunatoa ptrace/mdbg juu ya michakato mingine:

c
void set_ucred_to_debugger(){
struct proc* proc = get_proc_by_pid(getpid());
if (proc){
uintptr_t authid = 0; // read current (optional)
uintptr_t ptrace_authid = 0x4800000000010003ULL; // debugger Authority ID
kernel_copyout((uintptr_t)proc->p_ucred + 0x58, &authid, sizeof(uintptr_t));
kernel_copyin(&ptrace_authid, (uintptr_t)proc->p_ucred + 0x58, sizeof(uintptr_t));
free(proc);
}
}
  • Offset 0x58 ni maalum kwa familia ya firmware ya PS5 na lazima uhakikishe kwa kila toleo.
  • Baada ya uandishi huu, injector anaweza kuambatisha na ku-instrument michakato ya mtumiaji kupitia ptrace/mdbg.

Kupita mipangilio ya mtumiaji zenye RW tu: vm_map PROT_EXEC flip

mmap ya userland inaweza kuwa imezuiwa kwa PROT_READ|PROT_WRITE. FreeBSD inafuatilia nafasi ya anwani ya mchakato katika vm_map ya vm_map_entry nodes (BST plus list). Kila entry ina fields za protection na max_protection:

c
struct vm_map_entry {
struct vm_map_entry *prev,*next,*left,*right;
vm_offset_t start, end, avail_ssize;
vm_size_t adj_free, max_free;
union vm_map_object object; vm_ooffset_t offset; vm_eflags_t eflags;
vm_prot_t protection; vm_prot_t max_protection; vm_inherit_t inheritance;
int wired_count; vm_pindex_t lastr;
};

Kwa kernel R/W unaweza kupata vm_map ya target na kuweka entry->protection |= PROT_EXEC (na, inapohitajika, entry->max_protection). Vidokezo vya utekelezaji wa vitendo:

  • Pitia entries ama kwa mstari kupitia next au kutumia balanced-tree (left/right) kwa utafutaji wa O(log n) kwa anuwai ya anwani.
  • Chagua eneo la RW unalodhibiti (scratch buffer au mapped file) na ongeza PROT_EXEC ili uweze stage code au loader thunks.
  • PS5 SDK code hutoa helpers kwa fast map-entry lookup na kubadili protections.

Hii inazidi sera ya mmap ya userland kwa kuhariri metadata inayomilikiwa na kernel moja kwa moja.

Remote Function Invocation (RFI) kwa ptrace

FreeBSD lacks Windows-style VirtualAllocEx/CreateRemoteThread. Badala yake, endesha target iite functions yenyewe chini ya udhibiti wa ptrace:

  1. Unganisha kwa target na chagua thread; PTRACE_ATTACH au PS5-specific mdbg flows zinaweza kutumika.
  2. Hifadhi thread context: registers, PC, SP, flags.
  3. Andika argument registers kwa mujibu wa ABI (x86_64 SysV au arm64 AAPCS64), weka PC kwa function lengwa, na hiari weka args/stack za ziada kama zinahitajika.
  4. Fanya single-step au continue hadi kusimama kwa udhibiti (mf. software breakpoint au signal), kisha soma thamani za kurudi kutoka regs.
  5. Rejesha context ya awali na endelea.

Matumizi:

  • Piga simu katika ELF loader inayofanya kazi ndani ya mchakato (mf. elfldr_load) ukitumia pointer kwa ELF image yako iliyoko kwenye memory ya target.
  • Iita helper routines ili kuchukua entrypoints zilizorejeshwa na pointers za payload-args.

Mfano wa kuendesha ELF loader:

c
intptr_t entry = elfldr_load(target_pid, (uint8_t*)elf_in_target);
intptr_t args  = elfldr_payload_args(target_pid);
printf("[+] ELF entrypoint: %#02lx\n[+] Payload Args: %#02lx\n", entry, args);

Loader huweka ramani za segments, hutatua imports, hutumia relocations na hurudisha entry (mara nyingi CRT bootstrap) pamoja na opaque payload_args pointer ambayo stager yako hupitisha kwa payload’s main().

Threaded stager and clean detach

Stager ndogo ndani ya target inaunda pthread mpya ambayo inaendesha ELF’s main kisha inachochea int3 ili kutoa ishara kwa injector ili idetach:

c
int __attribute__((section(".stager_shellcode$1"))) stager(SCEFunctions* functions){
pthread_t thread;
functions->pthread_create_ptr(&thread, 0,
(void*(*)(void*))functions->elf_main, functions->payload_args);
asm("int3");
return 0;
}
  • Viashiria SCEFunctions/payload_args vinatolewa na loader/SDK glue.
  • Baada ya breakpoint na detach, payload inaendelea kwenye thread yake mwenyewe.

Mchakato kutoka mwanzo hadi mwisho (utekelezaji wa rejea wa PS5)

Tekelezaji unaofanya kazi hutolewa kama server ndogo ya TCP injector pamoja na client script:

  • NineS server inasikiliza kwenye TCP 9033 na inapokea header inayojumuisha jina la mchakato lengwa ikifuatiwa na ELF image:
c
typedef struct __injector_data_t{
char       proc_name[MAX_PROC_NAME];
Elf64_Ehdr elf_header;
} injector_data_t;
  • Matumizi ya mteja wa Python:
bash
python3 ./send_injection_elf.py SceShellUI hello_world.elf <PS5_IP>

Mfano wa payload ya Hello-world (logs kwa klog):

c
#include <stdio.h>
#include <unistd.h>
#include <ps5/klog.h>
int main(){
klog_printf("Hello from PID %d\n", getpid());
return 0;
}

Mambo ya vitendo

  • Offsets na konstanti (allproc, ucred authority offset, vm_map layout, ptrace/mdbg details) ni maalum kwa firmware na lazima zisasishwe kwa kila toleo.
  • Ulinzi wa hypervisor unalazimisha maandishi ya kernel ya data-only; usijaribu patch CR0.WP au CR4.SMEP.
  • Kumbukumbu ya JIT ni mbadala: baadhi ya michakato huonyesha PS5 JIT APIs za kutenga kurasa executable. The vm_map protection flip yanaondoa uhitaji wa kutegemea mbinu za JIT/mirroring.
  • Hakikisha register save/restore yako iko imara; kwa kushindwa, unaweza kusababisha deadlock au crash kwa lengo.

Zana za umma

  • PS5 SDK (dynamic linking, kernel R/W wrappers, vm_map helpers): https://github.com/ps5-payload-dev/sdk
  • ELF loader: https://github.com/ps5-payload-dev/elfldr
  • Injector server: https://github.com/buzzer-re/NineS/
  • Utilities/vm_map helpers: https://github.com/buzzer-re/playstation_research_utils
  • Related projects: https://github.com/OpenOrbis/mira-project, https://github.com/ps5-payload-dev/gdbsrv

Marejeo

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks