code injection on Mojave

Questions and Answers about all things *OS (macOS, iOS, tvOS, watchOS)

code injection on Mojave

Postby scknight » Sun Feb 24, 2019 10:08 pm

It looks like in 10.14 and above pthread_set_self was split up into a dyld specific one called _pthread_set_self_dyld along with the normal internal one. I'm trying to inject code into another process similar to the example here

http://newosxbook.com/src.jl?tree=listi ... e=inject.c

Since NULL isn't a valid value anymore to pthread_set_self. I tried allocating memory for a pthread_t struct and passing that in as the arguement to pthread_set_self but the dlopen still crashes.

Is there any known example of working code injection on 10.14 and above?
scknight
 
Posts: 56
Joined: Thu Nov 10, 2016 1:01 pm

Re: code injection on Mojave

Postby morpheus » Sun Feb 24, 2019 11:23 pm

I wasn't aware of this (haven't tried on Mojave). I'll get to fixing this by updating the code ASAP.
morpheus
Site Admin
 
Posts: 687
Joined: Thu Apr 11, 2013 6:24 pm

Re: code injection on Mojave

Postby scknight » Mon Feb 25, 2019 1:37 pm

I also tried calling _pthread_main_thread_np and explicitly passing in the main thread to _pthread_set_self, which would seem to be similar to what was happening in the old libpthread version when you passed in NULL to pthread_set_self. This just seems to crash the main thread when dlopen is called. The other idea I had, at least for mojave was to call _pthread_allocate to create and set up a proper pthread_t struct and pass that into pthread_set_self but that method isn't there on older versions. Ultimately I'd hope to keep something working on multiple versions on macOS. I'll post back here if I get things working.
scknight
 
Posts: 56
Joined: Thu Nov 10, 2016 1:01 pm

Re: code injection on Mojave

Postby scknight » Mon Feb 25, 2019 5:58 pm

So I believe I got this working. I tested on Mojave and High Sierra

Code: Select all
// "\xCC"                            // int3

"\x55"                            // push       rbp
"\x48\x89\xE5"                    // mov        rbp, rsp
"\x48\x83\xEC\x10"                // sub        rsp, 0x10
"\x48\x8D\x7D\xF8"                // lea        rdi, qword [rbp+var_8]       
"\x31\xC0"                        // xor        eax, eax
"\x89\xC1"                        // mov        ecx, eax                     
"\x48\x8D\x15\x1A\x00\x00\x00"    // lea        rdx, qword ptr [rip + 0x1A] 
"\x48\x89\xCE"                    // mov        rsi, rcx                     
"\x48\xB8"                        // movabs     rax, pthread_create_from_mach_thread
"PTHRDCRT"
"\xFF\xD0"                        // call       rax
"\x89\x45\xF4"                    // mov        dword [rbp+var_C], eax
"\x48\x83\xC4\x10"                // add        rsp, 0x10
"\x5D"                            // pop        rbp
"\xEB\xFE"                        // jmp        0x0
"\xC3"                            // ret

"\x55"                            // push       rbp                         
"\x48\x89\xE5"                    // mov        rbp, rsp
"\x48\x83\xEC\x10"                // sub        rsp, 0x10
"\xBE\x01\x00\x00\x00"            // mov        esi, 0x1
"\x48\x89\x7D\xF8"                // mov        qword [rbp+var_8], rdi   
"\x48\x8D\x3D\x1D\x00\x00\x00"    // lea        rdi, qword ptr [rip + 0x2c] 
"\x48\xB8"                        // movabs     rax, dlopen
"DLOPEN__"               
"\xFF\xD0"                        // call       rax
"\x31\xF6"                        // xor        esi, esi
"\x89\xF7"                        // mov        edi, esi
"\x48\x89\x45\xF0"                // mov        qword [rbp+var_10], rax
"\x48\x89\xF8"                    // mov        rax, rdi
"\x48\x83\xC4\x10"                // add        rsp, 0x10
"\x5D"                            // pop        rbp
"\xC3"                            // ret

"LIBLIBLIBLIB"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";


Above is my updated thread code. instead of trying to call pthread_set_self and half initializing the pthread it looks like there's a pthread_create_from_mach_thread function. This function has the comment "A version of pthread_create that is safely callable from an injected mach thread." so it would seem to be specifically created for this situation. The assembly above creates to functions and the first just calls pthread_create_from_mach_thread passing in the second procedures location. The second procedure then simply calls dlopen.

Annoyingly, this approach doesn't work if the software was built with the hardened runtime enabled. In that case you'll get a message from amfid like this

2019-02-25 12:23:43.376418-0500 0x3d6f2c Error 0x0 0 0 kernel: (AppleMobileFileIntegrity) Library Validation failed: Rejecting './libinjectme.dylib' (Team ID: AAAAAAA, platform: no) for process 'Application(64064)' (Team ID: BBBBBB, platform: no), reason: mapping process and mapped file (non-platform) have different Team IDs'.

I haven't tested yet when SIP is disabled to see if that also disabled the hardened runtime checking.
scknight
 
Posts: 56
Joined: Thu Nov 10, 2016 1:01 pm

Re: code injection on Mojave

Postby ccnut » Thu Apr 11, 2019 8:43 pm

I can't say for certain, but the error you are seeing when injecting:

2019-02-25 12:23:43.376418-0500 0x3d6f2c Error 0x0 0 0 kernel: (AppleMobileFileIntegrity) Library Validation failed: Rejecting './libinjectme.dylib' (Team ID: AAAAAAA, platform: no) for process 'Application(64064)' (Team ID: BBBBBB, platform: no), reason: mapping process and mapped file (non-platform) have different Team IDs'


Seems to indicate that the process you are injecting into likely has the CS flag CS_REQUIRE_LV set, which requires that the TEAMID in the target process and to-inject dylib are the same. Try setting your TEAMID to match and resigning to be sure. If true, it has little to do with the approach and all to do with the in-kernel checks for exactly this precondition. Otherwise the dylib will not be loaded.
ccnut
 
Posts: 7
Joined: Fri Mar 15, 2019 5:11 pm


Return to Questions and Answers

Who is online

Users browsing this forum: No registered users and 2 guests