Skip to content

Instantly share code, notes, and snippets.

@wh1te4ever
Last active April 21, 2024 00:30
Show Gist options
  • Save wh1te4ever/e6984ddef2c365afdd085315a1a9dac3 to your computer and use it in GitHub Desktop.
Save wh1te4ever/e6984ddef2c365afdd085315a1a9dac3 to your computer and use it in GitHub Desktop.
Bypass sandbox restriction 'mpo_file_check_mmap' via kernel patch (file system sandbox blocked mmap)
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define T1SZ_BOOT 17
#define off_p_pfd 0xf8
#define off_fp_glob 0x10
#define off_fg_data 0x38
#define off_vnode_v_flag 0x54
#define off_vnode_v_iocount 0x64
#define off_vnode_v_usecount 0x60
#define VSHARED_DYLD 0x000200
static void *libjb = NULL;
static const char* libraries[21] = {
"venv/lib/python3.9/site-packages/orjson/orjson.cpython-39-darwin.so",
"venv/lib/python3.9/site-packages/charset_normalizer/md__mypyc.cpython-39-darwin.so",
"venv/lib/python3.9/site-packages/lxml/etree.cpython-39-darwin.so",
"venv/lib/python3.9/site-packages/lxml/_elementpath.cpython-39-darwin.so",
"venv/lib/python3.9/site-packages/Crypto/Cipher/_raw_ecb.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Cipher/_raw_cbc.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Cipher/_raw_cfb.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Cipher/_raw_ofb.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Cipher/_raw_ctr.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Util/_strxor.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Hash/_BLAKE2s.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Hash/_SHA1.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Hash/_SHA256.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Cipher/_Salsa20.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Protocol/_scrypt.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Util/_cpuid_c.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Hash/_ghash_portable.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Cipher/_raw_ocb.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Cipher/_raw_aes.abi3.so",
"venv/lib/python3.9/site-packages/Crypto/Cipher/_pkcs1_decode.abi3.so",
"venv/lib/python3.9/site-packages/charset_normalizer/md.cpython-39-darwin.so"
};
uint64_t unsign_kptr(uint64_t pac_kaddr) {
if ((pac_kaddr & 0xFFFFFF0000000000) == 0xFFFFFF0000000000) {
return pac_kaddr;
}
if(T1SZ_BOOT != 0) {
return pac_kaddr |= ~((1ULL << (64U - T1SZ_BOOT)) - 1U);
}
return pac_kaddr;
}
void kwrite64(uint64_t va, uint64_t v) {
void *libjb_kwrite64 = dlsym(libjb, "kwrite64");
int (*_kwrite64)(uint64_t va, uint64_t v) = libjb_kwrite64;
_kwrite64(va, v);
}
void kwrite32(uint64_t va, uint32_t v) {
void *libjb_kwrite32 = dlsym(libjb, "kwrite32");
int (*_kwrite32)(uint64_t va, uint32_t v) = libjb_kwrite32;
_kwrite32(va, v);
}
uint64_t kread64(uint64_t va) {
void *libjb_kread64 = dlsym(libjb, "kread64");
uint64_t (*_kread64)(uint64_t va) = libjb_kread64;
return _kread64(va);
}
uint32_t kread32(uint64_t va) {
void *libjb_kread32 = dlsym(libjb, "kread32");
uint32_t (*_kread32)(uint64_t va) = libjb_kread32;
return _kread32(va);
}
uint64_t proc_self(void)
{
void *libjb_proc_self = dlsym(libjb, "proc_self");
uint64_t (*_proc_self)(void) = libjb_proc_self;
uint64_t ret = _proc_self();
printf("proc_self = 0x%llx\n", ret);
return ret;
}
uint64_t getVnodeAtPath(uint64_t proc, char* filename) {
int file_index = open(filename, O_RDONLY);
if (file_index == -1) {
printf("open failed, filename = %s\n", filename);
exit(1);
}
uint64_t filedesc_pac = kread64(proc + off_p_pfd);
uint64_t filedesc = unsign_kptr(filedesc_pac);
uint64_t openedfile = kread64(filedesc + (8 * file_index));
uint64_t fileglob_pac = kread64(openedfile + off_fp_glob);
uint64_t fileglob = unsign_kptr(fileglob_pac);
uint64_t vnode_pac = kread64(fileglob + off_fg_data);
uint64_t vnode = unsign_kptr(vnode_pac);
close(file_index);
return vnode;
}
void vnode_ref(uint64_t vnode) {
uint32_t usecount = kread32(vnode + off_vnode_v_usecount);
kwrite32(vnode + off_vnode_v_usecount, usecount + 1);
}
void vnode_get(uint64_t vnode) {
uint32_t iocount = kread32(vnode + off_vnode_v_iocount);
kwrite32(vnode + off_vnode_v_iocount, iocount + 1);
}
void vnode_put(uint64_t vnode) {
uint32_t iocount = kread32(vnode + off_vnode_v_iocount);
if(iocount > 0)
kwrite32(vnode + off_vnode_v_iocount, iocount - 1);
}
void vnode_rele(uint64_t vnode) {
uint32_t usecount = kread32(vnode + off_vnode_v_usecount);
if(usecount > 0)
kwrite32(vnode + off_vnode_v_usecount, usecount - 1);
}
int jbdInitPPLRW(void) {
void *libjb_jbdInitPPLRW = dlsym(libjb, "jbdInitPPLRW");
int (*_jbdInitPPLRW)(void) = libjb_jbdInitPPLRW;
int ret = _jbdInitPPLRW();
printf("jbdInitPPLRW ret = %d\n", ret);
if(ret != 0) return 1;
return 0;
}
int main(int argc, char *argv[], char *envp[]) {
if(argc != 2)
return -1;
libjb = dlopen("/var/jb/basebin/libjailbreak.dylib", RTLD_NOW);
if(libjb == NULL) return -1;
if(jbdInitPPLRW()) return -1;
uint64_t selfproc = proc_self();
for(int i = 0; i < 21; i++) {
printf("libpath = %s\n", strrchr(libraries[i], '/'));
uint64_t vnode = getVnodeAtPath(selfproc, libraries[i]);
printf("libpath vnode = 0x%llx\n", vnode);
vnode_ref(vnode);
vnode_get(vnode);
uint32_t old_v_flags = kread32(vnode + off_vnode_v_flag);
uint32_t new_v_flags = old_v_flags;
if(strcmp(argv[1], "1") == 0)
new_v_flags = old_v_flags | VSHARED_DYLD;
else
new_v_flags = old_v_flags & ~VSHARED_DYLD;
printf("vnode->v_flags changed, old: 0x%x vs new: 0x%x\n", old_v_flags, new_v_flags);
kwrite32(vnode + off_vnode_v_flag, new_v_flags);
vnode_rele(vnode);
vnode_put(vnode);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment