Root with CVE-2019-2215?

chompie1337

Senior Member
Oct 2, 2019
99
30
0
We might be able to bypass it by using samfail or edl to write the exploit to system.
as far as I know, SAMFAIL will only let you load a modified system partition, not actually get write access to /system. i'm looking into how to remount either rootfs or system. sigh. this seriously never ends... i was so close!
 

f41lbl0g

Senior Member
Mar 15, 2014
296
422
93
as far as I know, SAMFAIL will only let you load a modified system partition, not actually get write access to /system. i'm looking into how to remount either rootfs or system. sigh. this seriously never ends... i was so close!
Technically we have write access to the system through safestrap. if you want to drop the app or poc in /system/priv-app it'll be in the system after boot but of course we wont have write access to the system when its booted. No clue how to remount them either.
 
Last edited:

chompie1337

Senior Member
Oct 2, 2019
99
30
0
Technically we have write access to the system through safestrap. if you want to drop the app or poc in /system/priv-app it'll be in the system after boot but of course we wont have write access to the system when its booted. No clue how to remount them either.
being able to write to /system and have it persist is enough, wouldn't need to remount. i though safestrap needed root or unlocked bl? can you link the relevant info? if what you're saying is true, then there's a strong chance there's a path forward.

i have an idea on how to force a remount on rootfs or system, but it's complex with Samsung RKP. not ruling it out yet.
 

Supersonic27543

Senior Member
Nov 14, 2016
646
318
63
It has to happen before find_kallsyms_addresses() starts going through memory. You can do it in loadKallsyms() if you like or in find_kallsyms_addresses().

By the way, on a device with KASLR, how do you recognize a kernel pointer?
Finally managed to break KASLR after adding some ugly workarounds! ANDing the search_base increased the entries in one search so I ANDed it with ~0xFFFFF instead, which increased it more. It looks like the problem is 30 addresses in the middle of the kallsyms table are decreasing, or somehow detected as such by the function. I added some code to just skip over it and set the address and entry count accordingly and now loadKallsyms works properly. (Verified this by setting kptr_restrict to 0, now the kernel addresses are visible in /proc/kallsyms :D)
Unfortunately for some reason, setting hkip bits to 1 doesn't seem to disable it, because it reads the bits from an array in a header named READ_ONCE, I haven't looked into how it is allocated yet.
BTW I don't think disabling it would be required if we can somehow mask SIGKILL using the kernel r/w. Does someone know whether this may be possible? (Maybe by overwriting something in the task_struct?)
Thank you!
EDIT: The process is killed by using force_sig (see /kernel/signal.c for source) on the process. Could it be possible to disable as we have the address where it is located in /proc/kallsyms?
 
Last edited:

arpruss

Senior Member
Jul 3, 2010
847
413
0
pruss.mobi
Finally managed to break KASLR after adding some ugly workarounds! ANDing the search_base increased the entries in one search so I ANDed it with ~0xFFFFF instead, which increased it more. It looks like the problem is 30 addresses in the middle of the kallsyms table are decreasing, or somehow detected as such by the function.
That's so weird. Do they show up as decreasing now that you've got /proc/kallsyms working? Can you post the relevant section of /proc/kallsyms?
 

f41lbl0g

Senior Member
Mar 15, 2014
296
422
93
being able to write to /system and have it persist is enough, wouldn't need to remount. i though safestrap needed root or unlocked bl? can you link the relevant info? if what you're saying is true, then there's a strong chance there's a path forward.

i have an idea on how to force a remount on rootfs or system, but it's complex with Samsung RKP. not ruling it out yet.
Doesn't require an unlocked bl. I don't know if it works for the s8 active but it does work on the regular s8/+. I'm currently on safestrap pie right now but I am downgrading to oreo soon. I can flash zips to /system (including some audio mods, xposed, adblock, debloater, replace fonts and emojis) and use the safestrap file manager (same as twrp file manager) to read/write files and change permissions. Flashing a modified magisk to system (without touching (kernel) flashes fine but runs into selinux issues, which I hope we can fix using this exploit.

Here is the link to it for the regular s8:
https://forum.xda-developers.com/showpost.php?p=76074958&postcount=3

If you are on bootloader 1 or 2 there may be a chance of safestrap on the active.
 
Last edited:

afaneh92

Senior Member
Jul 31, 2012
2,097
3,978
203
being able to write to /system and have it persist is enough, wouldn't need to remount. i though safestrap needed root or unlocked bl? can you link the relevant info? if what you're saying is true, then there's a strong chance there's a path forward.

i have an idea on how to force a remount on rootfs or system, but it's complex with Samsung RKP. not ruling it out yet.
PM for safestrap support on oreo.
 

Supersonic27543

Senior Member
Nov 14, 2016
646
318
63
That's so weird. Do they show up as decreasing now that you've got /proc/kallsyms working? Can you post the relevant section of /proc/kallsyms?
Code:
ffffff94c3385250 r proc_bg_uids_operations
ffffff94c3385328 r proc_fg_uids_operations
ffffff94c3385400 r proc_aware_ctrl_operations
# the gap
ffffff94c38ba780 R capability_hooks
ffffff94c38ba9c0 R security_hook_heads
ffffff94c38bb4c0 R selinux_enabled
ffffff94c38bb4c8 r selinux_hooks
ffffff94c38bc988 r selinux_nf_ops
There seems to be a huge gap there, maybe that's the case? The exploit is jumping from 0xffffff94c33f0c10 to 0xffffff94c33f0d00. Thanks!
 

Supersonic27543

Senior Member
Nov 14, 2016
646
318
63
@chompie1337 Now that I have bypassed KASLR, I looked into the methods used in that Knox bypass paper, and have a couple of questions. Seeing that you have utilized some of those, would really appreciate if you can share what you think.
First, after overwriting poweroff_cmd, how do you call orderly_poweroff? I'm not sure how to call a kernel function from user space.
And the paper says ss_initialized should be recovered ASAP because else the file system could be corrupted. Is this a real concern? (As in could it corrupt important partitions like system, boot/ramdisk, etc. or just sdcard, or nothing?)
Thank you!
 
Last edited:

chompie1337

Senior Member
Oct 2, 2019
99
30
0
@chompie1337 Now that I have bypassed KASLR, I looked into the methods used in that Knox bypass paper, and have a couple of questions. Seeing that you have utilized some of those, would really appreciate if you can share what you think.
First, after overwriting poweroff_cmd, how do you call orderly_poweroff? I'm not sure how to call a kernel function from user space.
And the paper says ss_initialized should be recovered ASAP because else the file system could be corrupted. Is this a real concern? (As in could it corrupt important partitions like system, boot/ramdisk, etc. or just sdcard, or nothing?)
Thank you!
overwriting ss_initialized doesn't work to bypass SELinux on my device, it may work for yours. I bypassed it other ways, but I would try the ss_initialized method first because it's easier. to answer your question, i don't think it's a real concern wrt to permanent damage to the file system. it might crash the device, that's why you're supposed to load a new sepolicy right away.

what I did to call orderly_poweroff is to overwrite the file_operations pointer for a random file I create. I overwrite the check_flags pointer to point to orderly_power using kernel write. then I call fcntl with the F_SETFL flag which will call orderly_poweroff in the kernel. this queues up a kernel thread to execute whatever executable is in the poweroff_cmd string. this is when SELinux should block you, but let me know when you get this far.

---------- Post added at 09:15 PM ---------- Previous post was at 09:05 PM ----------

Doesn't require an unlocked bl. I don't know if it works for the s8 active but it does work on the regular s8/+. I'm currently on safestrap pie right now but I am downgrading to oreo soon. I can flash zips to /system (including some audio mods, xposed, adblock, debloater, replace fonts and emojis) and use the safestrap file manager (same as twrp file manager) to read/write files and change permissions. Flashing a modified magisk to system (without touching (kernel) flashes fine but runs into selinux issues, which I hope we can fix using this exploit.

Here is the link to it for the regular s8:
https://forum.xda-developers.com/showpost.php?p=76074958&postcount=3

If you are on bootloader 1 or 2 there may be a chance of safestrap on the active.
i'm on bl4. i actually do think this could work because writing a program to /system would execute in the kernel context and could load a new sepolicy making the magisk context (essentially) permissive.
i'll look into it if i can try with the active. i have a normal s8 but it's on pie.
 
Last edited:
  • Like
Reactions: Supersonic27543

f41lbl0g

Senior Member
Mar 15, 2014
296
422
93
overwriting ss_initialized doesn't work to bypass SELinux on my device, it may work for yours. I bypassed it other ways, but I would try the ss_initialized method first because it's easier. to answer your question, i don't think it's a real concern wrt to permanent damage to the file system. it might crash the device, that's why you're supposed to load a new sepolicy right away.

what I did to call orderly_poweroff is to overwrite the file_operations pointer for a random file I create. I overwrite the check_flags pointer to point to orderly_power using kernel write. then I call fcntl with the F_SETFL flag which will call orderly_poweroff in the kernel. this queues up a kernel thread to execute whatever executable is in the poweroff_cmd string. this is when SELinux should block you, but let me know when you get this far.

---------- Post added at 09:15 PM ---------- Previous post was at 09:05 PM ----------



i'm on bl4. i actually do think this could work because writing a program to /system would execute in the kernel context and could load a new sepolicy making the magisk context (essentially) permissive.
i'll look into it if i can try with the active. i have a normal s8 but it's on pie.
As long as your s8 (regular) is not on the latest bootloader (v6), it is possible to downgrade your phone to oreo on the s8 with safestrap. I believe @afaneh92 does have safestrap oreo on his s8 active so pm him. If you need someone to test your exploit on the s8+ on oreo with safestrap you can pm me as well.
 
Last edited:

ethylamine

New member
Nov 11, 2019
4
2
0
Hey guys, great work going on here. I've done a bit of research on this topic and found this forum to be the most active regarding development of a temproot. I was wondering if this CVE can lead to at least temproot on my samsung galaxy S6 edge+ (SM-G928A).
As far as I know, this particular model has never had anything done to it thanks to AT&T. I'm running a very old version of the android kernel (3.10.61-12579816). From what I found, this model on this kernel version should be susceptible to the exploit. This repo is the closest thing to source I can find as well https://github.com/jcadduono/android_kernel_samsung_universal7420
I've extracted the kernel from the firmware image and found the offsets for BINDER_THREAD_SIZE and WAITQUEUE_OFFSET. I know knox must be bypassed as well.
Is it feasible to get a temproot going despite the project 0 team not mentioning the S6 altogether? Also, could anyone link the latest version of su98? The repo is gone and if I'm going to start running the exploit on my phone I want a "clean slate" so to speak.
Thanks in advance.
 

Supersonic27543

Senior Member
Nov 14, 2016
646
318
63
@chompie1337 Reading an uint from ss_initialized gave 136077328 and writing to this address gives an error (kallsyms says this is read only) Reading an ulong from ss_initialized gives something that looks like an address pointer which points to a 1 (uint) but this address is not writable either.
I looked at the source and ss_initialized (it works like it should BTW, goes to allow if it is 0) is defined with:
Code:
int *ss_initialized __ro_after_init;
So I guess it wouldn't work unless we can somehow safely disable CPU page write protection or trick the kernel into mapping this as writable.
Also as to the poweroff_cmd, if I understood it right the steps goes like this:
1) Overwrite poweroff_cmd string with our file address.
2) Create a file and get an address to the file struct with fdget.
3) Get file_operations struct address by reading the file struct address added to the correct offset.
4) Get the offset to check_flags pointer and overwrite with orderly_poweroff pointer.
5) Call fcntl with F_SETFL.
Does this look right? (I'm not sure how to get the offsets, I'm thinking about manually counting but not sure because there is some union{} before file_operations, so please tell if they could be looked up dynamically) Also is there any way to verify if it worked or not?
Thank you very much for helping! :)
 

Supersonic27543

Senior Member
Nov 14, 2016
646
318
63
Also because this device doesn't have DFI (I think) maybe we can just use the init process's creds, if we can just bypass HKIP (it kills the process when it tries to use init creds) Masking SIGKILL should be enough to bypass this. :)
 
Last edited:

chompie1337

Senior Member
Oct 2, 2019
99
30
0
@chompie1337 Reading an uint from ss_initialized gave 136077328 and writing to this address gives an error (kallsyms says this is read only) Reading an ulong from ss_initialized gives something that looks like an address pointer which points to a 1 (uint) but this address is not writable either.
I looked at the source and ss_initialized (it works like it should BTW, goes to allow if it is 0) is defined with:
Code:
int *ss_initialized __ro_after_init;
So I guess it wouldn't work unless we can somehow safely disable CPU page write protection or trick the kernel into mapping this as writable.
Also as to the poweroff_cmd, if I understood it right the steps goes like this:
1) Overwrite poweroff_cmd string with our file address.
2) Create a file and get an address to the file struct with fdget.
3) Get file_operations struct address by reading the file struct address added to the correct offset.
4) Get the offset to check_flags pointer and overwrite with orderly_poweroff pointer.
5) Call fcntl with F_SETFL.
Does this look right? (I'm not sure how to get the offsets, I'm thinking about manually counting but not sure because there is some union{} before file_operations, so please tell if they could be looked up dynamically) Also is there any way to verify if it worked or not?
Thank you very much for helping! :)
yes, but you won't be able to use fdget. you'll have to look at your kernel for offsets. not too bad :). to confirm you have the right file_operations pointer, you can look at the addresses in there and check to see if they corresponds to the right functions (read/write/etc).

on my device i could not write directly to the memory of file_operations , but i could replace the file_operations pointer (if that makes sense). i used some memory near poweroff_cmd because it's writeable and mostly empty.

---------- Post added at 06:36 PM ---------- Previous post was at 06:35 PM ----------

Also because this device doesn't have DFI (I think) maybe we can just use the init process's creds, if we can just bypass HKIP (it kills the process when it tries to use init creds) Masking SIGKILL should be enough to bypass this. :)
i don't know what you mean by masking SIGKILL. you mean masking the constant that gets passed to the kill function?
 
  • Like
Reactions: Supersonic27543

Supersonic27543

Senior Member
Nov 14, 2016
646
318
63
yes, but you won't be able to use fdget. you'll have to look at your kernel for offsets. not too bad :). to confirm you have the right file_operations pointer, you can look at the addresses in there and check to see if they corresponds to the right functions (read/write/etc).

on my device i could not write directly to the memory of file_operations , but i could replace the file_operations pointer (if that makes sense). i used some memory near poweroff_cmd because it's writeable and mostly empty.

---------- Post added at 06:36 PM ---------- Previous post was at 06:35 PM ----------



i don't know what you mean by masking SIGKILL. you mean masking the constant that gets passed to the kill function?
Okay, thanks, will try implementing that! Sorry for not elaborating, I meant the signal variables in the task_struct (not sure if masking them would work to stop SIGKILL though), but any method to disable SIGKILL should do. Or if we have a way to disable specific kernel functions, just disabling the force_sig function temporarily (or permanently until boot if this is impossible) should be enough. (Would just zeroing out some memory starting from the force_sig symbol be enough? EDIT: This memory is not writeable)
Thank you!
 
Last edited:

Supersonic27543

Senior Member
Nov 14, 2016
646
318
63
@chompie1337 I managed to bypass Huawei protections and can get a root shell now! (still limited by SELinux and the context is still shell) I'm trying to get the orderly_poweroff thing working now. BTW if I can't use fdget how can I get a pointer to the file struct? Are there some other function I can use to get this? Would this work (but AFAIK "FILE" is different from "struct file")
Code:
FILE *file_struct=fopen("somefile","r");
Thank you!
 
Last edited: