yashsingh1/xdaforums huggingface dataset:
[LG V20 Questions & Answers] chompie1337:
nope, seems that the kstack is the correct location for thread_info + 0x8 on my kernel. kernel reading is successful but writing fails.
[LG V20 Questions & Answers] arpruss:
Can you post your su98 output?

It might also be worth checking if clobber_data() works with a target address inside user memory.

By the way, the writing code is actually simpler than reading arbitrary locations. Reading arbitrary memory took me forever to figure out. There are actually two parts to the leak_data() functionality. One part is easy: leak kernel heap memory starting with the location of the waitqueue tasklist. The second part is to leak arbitrary kernel memory. This is done by using clobber_data() to modify the iovec in the middle of the reading. On 3.18, the second part is needed for getting the stack address. On 4.4, the second part is not actually needed.
[LG V20 Questions & Answers] chompie1337:
yeah, i understand. its a clever technique, good work! it looks as though task_struct = thread_info in the parent process? in any case, i believe my addr_limit is getting clobberred because i'm able to complete some searches for offsets in the kernel. i added some of my own debug output but here's what i get:

1|cruiserlteatt:/ $ /data/local/tmp/su98
MAIN: detected kernel version 3
MAIN: starting exploit for devices with waitqueue at 0x98
PARENT: soon will be calling WRITEV
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: initial portion length 0x12000
CHILD: task_struct_ptr = 0xffffffc0b3302880
CHILD: clobbering with extra leak structures
PARENT: clobbering at 0xffffffc0f270fca0
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: wrote 69688
PARENT: readv returns 69688, expected 69688
PARENT: clobbering test passed
CHILD: clobbered
PARENT: writev() returns 0x13008
PARENT: Reading leaked data
CHILD: task_struct_ptr = 0xffffffc0a817c000
CHILD: Finished write to FIFO.
PARENT: leaking successful
MAIN: task_struct_ptr = ffffffc0b3302880
MAIN: stack = ffffffc0a817c000
MAIN: Clobbering addr_limit
PARENT: clobbering at 0xffffffc0a817c008
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: wrote 69648
PARENT: readv returns 69648, expected 69648
PARENT: clobbering test passed
MAIN: thread_info = 0xffffffc0a817c000
MAIN: should have stable kernel R/W now
MAIN: searching for cred offset in task_struct
read at addr ffffffc0b3302880
successful kernel read! ffffffc0b3302880
uid1 7d0
uid2 7d0
read at addr ffffffc0b3302fc0
successful kernel read! ffffffc0b3302fc0
MAIN: search_base = ffffffc000000000
MAIN: searching for selinux_enforcing
MAIN: searching for kallsyms format strings
read at addr ffffffc00196d020
successful kernel read! ffffffc00196d020
kernel writing at ffffffc00196d020 f
error with kernel writing: Bad address
[LG V20 Questions & Answers] arpruss:
Very good. So my write_primitive works, but the pipe based kernel rw code (which I lifted from the original poc) doesn't. So, here is an idea. On kernel 4, we can use clobber_data() for the writing. It's slow (almost a second per contiguous write), and less reliable (but one can retry), but there are only a few portions of memory that need writing (credentials, etc.). How does that sound?

You can test this concept by just changing raw_kernel_write:

int raw_kernel_write(unsigned long kaddr, void *buf, unsigned long len)
{
if (clobber_data(kaddr, buf, len))
return len;
else
return 0;
}

Tell me if it works. It actually works on 3.18, just is a lot slower.
[LG V20 Questions & Answers] chompie1337:
good idea! however, it still fails.

cruiserlteatt:/ $ /data/local/tmp/su98
MAIN: detected kernel version 3
MAIN: starting exploit for devices with waitqueue at 0x98
PARENT: soon will be calling WRITEV
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: initial portion length 0x12000
CHILD: task_struct_ptr = 0xffffffc08f23d100
CHILD: clobbering with extra leak structures
PARENT: clobbering at 0xffffffc0f09ec0a0
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: wrote 69688
PARENT: readv returns 69688, expected 69688
PARENT: clobbering test passed
CHILD: clobbered
PARENT: writev() returns 0x13008
PARENT: Reading leaked data
CHILD: task_struct_ptr = 0xffffffc0a58c0000
CHILD: Finished write to FIFO.
PARENT: leaking successful
MAIN: task_struct_ptr = ffffffc08f23d100
MAIN: stack = ffffffc0a58c0000
MAIN: Clobbering addr_limit ffffffc0a58c0000
PARENT: clobbering at 0xffffffc0a58c0008
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: wrote 69648
PARENT: readv returns 69648, expected 69648
PARENT: clobbering test passed
MAIN: thread_info = 0xffffffc0a58c0000
MAIN: should have stable kernel R/W now
MAIN: searching for cred offset in task_struct
read at addr ffffffc08f23d100
successful kernel read! ffffffc08f23d100
uid1 7d0
uid2 7d0
read at addr ffffffc08f23d840
successful kernel read! ffffffc08f23d840
MAIN: search_base = ffffffc000000000
MAIN: searching for selinux_enforcing
MAIN: searching for kallsyms format strings
read at addr ffffffc00196d020
successful kernel read! ffffffc00196d020
kernel writing at ffffffc00196d020 f
PARENT: clobbering at 0xffffffc00196d020
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: wrote 69655
PARENT: readv returns 69632, expected 69655
PARENT: **fail** clobber value doesn't match: is 0 but should be abcddeadbeef1234
error with kernel writing: error

this leads me to believe that it's just a non writeable spot in memory. i think it's the kallsyms format strings

to confirm, i did a test doing a write a NULL bytes at the beginning of the thread_info_ptr (with the pipe kernel write) and it was successful.

char buf2 = 0x0;
message("doing write test now");
kernel_write(thread_info_ptr, &buf2, 1);
[LG V20 Questions & Answers] arpruss:
OK, I see. On my device, one can write to the format strings, but I guess not on others. I made the code have a cleaner fail now, and it should fall back to searching through kernel memory for the actual kallsyms.

You can also get around all of this nuisance with kallsyms by finding out the selinux_enforcing symbol address in some other way (e.g., droidimg on the kernel image) and putting the value (in hex, without 0x) in a file named selinux_enforcing.symbol in the same directory as su98.
[LG V20 Questions & Answers] chompie1337:
thx. wasn't able to find kallsyms table but i'll deal with that later. do you know if you have to disable SELinux before overwriting the cred struct? i tried just overwriting UID and i'm crashing.

---------- Post added at 12:21 AM ---------- Previous post was at 12:01 AM ----------

ugh.

from here: https://www.samsungknox.com/en/blog/real-time-kernel-protection-rkp

back to the drawing board i guess
[LG V20 Questions & Answers] antintin:
Should it work on lg v50 that doesnt have the kernel protection already though?
[LG V20 Questions & Answers] jc9896:
Using the su98 from github, I could obtain root shell on my G5 (H860)
[LG V20 Questions & Answers] antintin:
Now someone just needs to add it to qu1ckr00t so magisk can be installed
[LG V20 Questions & Answers] Supersonic27543:
I think you can just copy the Magisk script and binaries from there and run, no need to compile the whole app.
[LG V20 Questions & Answers] antintin:
I guess. I can't really tell myself, but can someone who knows what they're doing say how close the poc is to running on 4.4 without Samsung kernel protection?
[LG V20 Questions & Answers] Supersonic27543:
I'm not familiar with the internal workings of this exploit but judging by the replies here I'd say that it is quite close because it could achieve arbitrary kernel R/W. [MENTION=2714177]arpruss[/MENTION] and [MENTION=10174047]chompie1337[/MENTION] could probably tell you more.
[LG V20 Questions & Answers] chompie1337:
post your output, do you know your waitqueje offsets? it should be ready now if you have a compatible device
[LG V20 Questions & Answers] Supersonic27543:
My 4.4 device still crashes unless kernel3 is forced to 1, maybe the correct location is kstack for my kernel too. I added some debug output and it fails to read any kernel data (bad address) AFAIK Huawei doesn't have any of those special protections in place either, just vanilla Android ones like PXN, ASLR, KASLR, SECCOMP etc.

(Also, the exploit getting this far should mean that the kernel is vulnerable, right?)
[LG V20 Questions & Answers] chompie1337:
Yes your kernel is definitely vulnerable. My suspicion is that the address being clobbered is incorrect (thread_info->addr_limit, giving you permission to R/W in the kernel) . Do you have approximate source for your kernel?

---------- Post added at 07:25 AM ---------- Previous post was at 07:16 AM ----------

I still have the extracted kernel from your firmware so I can take a look at it a little later. It'd be easier if you had source (even if it's not exact)
[LG V20 Questions & Answers] Supersonic27543:
This kernel source should be really close. Same SoC, kernel version and Android version. Thanks!

---------- Post added at 12:05 PM ---------- Previous post was at 11:58 AM ----------

Also I already have that source downloaded, so if you want just a couple of files I can upload them.
[LG V20 Questions & Answers] chompie1337:
No worries I’m downloading. It’d just be a hassle to ask you for more bc i don’t know off the top of my head. For reference, I’m just going to check the definitions of task_struct and thread_info and see if they match up with what’s in su98
[LG V20 Questions & Answers] elliwigy:
just droppin in to confirm the su98 poc works.. got a cheap H918 from a crack head at the store other day for 15$ lol. it was goog locked. I bypassed frp and was able to perm sim unlock in the tmo app. I then unlocked bl in dev settings and fastboot. I then ran su98 poc in adb n got a root shell. i then installed magisk manager and pulled the boot.img and patched with magisk. i then used dd to write it back and rebooted. now im on latest oreo with magisk.. i imagine root could prolly b used to write twrp but i dont really need it.. beats having to use lafsploit or dirty santa or downgrade or do the fwul stuff etc.
[LG V20 Questions & Answers] chompie1337:
I found the problem.

In your kernel, the position of thread_info is randomized on the kstack.

#ifdef CONFIG_HUAWEI_KERNEL_STACK_RANDOMIZE_STRONG
extern unsigned long kti_offset;
static inline struct thread_info *current_thread_info(void)
{
unsigned long sp_el0;

asm ("mrs %0, sp_el0" : "=r" (sp_el0));

return (struct thread_info *)(sp_el0 + kti_offset);
}

(register sp_el0 stores the kstack pointer)

The config file shows CONFIG_HUAWEI_KERNEL_STACK_RANDOMIZE_STRONG for your kernel is set. kti_offset is set randomly on boot. this can easily be fixed by leaking the entire kstack and search for USER_FS to find addr_limit. It's late where I live so I'll probably give it a shot tmrw unless [MENTION=2714177]arpruss[/MENTION] wants to add that

by the way, this kernel also had the same bug I found yesterday needing the BINDER_MAX_THREAD adjustment. so hopefully that patch has expanded support for more devices.
[LG V20 Questions & Answers] chompie1337:
[MENTION=7860599]Supersonic27543[/MENTION]

Can you compile this and tell me if this changes anything for you? (Change your waitqueue and binder size definitions accordingly)
[LG V20 Questions & Answers] sansjz:
Anyone successful in doing this for their Xiomi MI A1 device? following is the version I'm at (output for uname -a):

Linux localhost 3.18.120-perf-gd91300b #1 SMP PREEMPT Mon Aug 12 11:52:18 WIB 2019 aarch64

I'm able to get this working on my pixel 2 (android 10 - exact same as the Quickroot post), but not on Pixel 2 Android 9.. I want to test install a system app on android 10, but I don't think it's possible, that's why trying to get root on Android 9 Pixel 2 or Android 9 MI A1.. Any help would be greatly appreciated!
[LG V20 Questions & Answers] Supersonic27543:
It is not possible to install custom system apps without unlocking the bootloader on Android 6 or after (Doing that will brick the device) And if you can unlock the bootloader (and IIRC it is easily possible in both A1 and Pixel 2) no need to do this, just flash Magisk! :) After that you can mount system R/W, copy the APK to /system/priv-app and reboot
[LG V20 Questions & Answers] sansjz:
ah, ok. wasn't aware of this. basically wanted to enable call recording of normal and voip calls.. which i saw somewhere only system apps allow. many tutorials post installing system app simply as remounting the /system and dropping the APK in /system/app and rebooting? won't that work with this exploit?
[LG V20 Questions & Answers] Supersonic27543:
No, on Marshmallow and later this will just brick the device. :(
[LG V20 Questions & Answers] Rortiz2:
Hi all,

This thread looks pretty nice!

I just tried the latest poc in github but the only thing I can get is a reboot xD.

Huawei P10 Lite WAS-LX1A. Kernel 4.4.23+.

r0rtiz2@r0rtiz2-X540LA:~/Descargas$ adb shell
:/ $ cd data
:/data $ cd local
:/data/local $ cd tmp
:/data/local/tmp $ chmod 755 *
:/data/local/tmp $ ls
su98
:/data/local/tmp $ ./su98
MAIN: detected kernel version other than 3
MAIN: starting exploit for devices with waitqueue at 0x98
PARENT: soon will be calling WRITEV

It stucks there and reboot.

It was just for test!

Cheers.
[LG V20 Questions & Answers] Supersonic27543:
Hey, nice to see you here! :D That's likely because the waitqueue offset or the binder thread size is incorrect (the defines at start) Maybe 0x198 for binder thread size and 0xa8 for the waitqueue would work as they were the values for my Huawei device. You can check post #52 on how to extract those from the kernel image.
[LG V20 Questions & Answers] Rortiz2:
Haha cool! If I get at least temp root, we can read the unlock code from NVME partition:)

Did it worked on your Huawei?

Cheers!
[LG V20 Questions & Answers] Supersonic27543:
I can get arbitrary kernel R/W, but something goes wrong when searching SELinux address to disable it. :)
[LG V20 Questions & Answers] Supersonic27543:
I incorporated the debug console (to read/write kernel memory, I removed other options) from here to the su98 with kstack patch by [MENTION=10174047]chompie1337[/MENTION] and restored the pipe kernel write (also the defines are changed from the original to those of my device) The code is a little ugly because I just threw it together without cleaning up, sorry for that.

BTW if we can leak just one kernel pointer we can bypass KASLR, right? I don't see any recent kernel pointer leak vulnerabilities though.
[LG V20 Questions & Answers] antintin:
If root shell started fully working on 4.4x would it be possible to unlock bootloader manually by changing some values manually? I don't even have access to fastboot so I can't the use an unlock code.
[LG V20 Questions & Answers] Supersonic27543:
I'm not aware of such a method unfortunately, and that would vary heavily among different OEMs. If it is possible it would probably be in your device's (or similar devices') forums. :) Good luck!
[LG V20 Questions & Answers] chompie1337:
great! now you have arbitrary r/w! unfortunately your kernel doesn't export selinux_enforcing. that doesn't mean you can't turn it off, but it'll be more complicated than flipping a bit.

if you get all the way thru the exploit without turning SELinux off and then pop a shell(is that what's happening?) you will probably run into issues. in any case if you want to post your kernel log, i'll take a look!
[LG V20 Questions & Answers] Supersonic27543:
Great to know! :) I don't have permissions to actually read the kernel log, I use logwrapper to add kernel log output to logcat, I don't know a way to seperate the kernel log. If it's okay I could send the whole logcat.

Both going all the way through the exploit and just popping a shell after UID=0 point gives the "Killed".
[LG V20 Questions & Answers] chompie1337:
yeah post your logcat. I’m curious
[LG V20 Questions & Answers] Supersonic27543:
This logcat should include the su98 process being killed at least once. Actually logwrapper to add kernel log doesn't work because not enough permissions, this is just a normal logcat. Thanks!
[LG V20 Questions & Answers] Supersonic27543:
Does that mean there's no selinux_enforcing address that can be flipped to disable SELinux? Or just that it is harder to find? Thanks!
[LG V20 Questions & Answers] arpruss:
I added randomized thread_info location search code to su98.

And someone sent me code to find selinux_enforcing on devices where it's not in kallsyms. I haven't inserted it yet.
[LG V20 Questions & Answers] arpruss:
I added [MENTION=8094126]DrZener[/MENTION] 's code for finding selinux_enforcing by parsing avc_denied.
[LG V20 Questions & Answers] DrZener:
Credit for this goes to [MENTION=8132642]diplomatic[/MENTION] and his mtk-su
[LG V20 Questions & Answers] Supersonic27543:
[MENTION=8094126]DrZener[/MENTION] and [MENTION=2714177]arpruss[/MENTION] (and of course to [MENTION=8132642]diplomatic[/MENTION] too :)) thanks for the update! Unfortunately the exploit fails to find the avc_denied address. Is it possible that my kernel doesn't export that too?

MAIN: direct search didn't work, so searching via avc_denied
CHILD: wrote 69648
MAIN: searching for kallsyms format strings
MAIN: **partial failure** cannnot fix kallsyms format string
MAIN: searching for kallsyms table
MAIN: **fail** cannot find kallsyms table
[LG V20 Questions & Answers] arpruss:
No, that's not the issue. The issue is that it can't find the kallsyms table at all. Does

cat /proc/kallsyms

do anything?

Also, try the su98 now in github and see if it prints any different messages.
[LG V20 Questions & Answers] DrZener:
Try to run

cat /proc/kallsyms | wc -l

and write here the output
[LG V20 Questions & Answers] Supersonic27543:
Your device looks 64-bit, but maybe your EMUI architecture is not 64-bit? I'm not actually sure whether that will be a problem or not, I didn't have to do that myself because my kernel was used in that post for demonstration. :) Anyway, good luck!

---------- Post added at 10:15 PM ---------- Previous post was at 10:14 PM ----------

That gives just "160849". (I didn't expect there to be that much kernel symbols) Thanks!
[LG V20 Questions & Answers] Rortiz2:
Yup is 64 bits. Anyway to get the address with Root? I'm root with Magisk xD.

I just want to port the exploit for other people :)
[LG V20 Questions & Answers] Supersonic27543:
I'm not aware of such a method unfortunately, but perhaps someone here is. :(

You should be able to take a longer route: Download your kernel source, add CONFIG_DEBUG_INFO to kernel config, compile it, and poke drivers/android/binder.o with pahole. I'm not sure how waitqueue is extracted exactly, (I think it's the number of bits in the "struct binder_thread" in binder.c before the "wait_queue_head_t" line but not sure) probably someone here could help if you send it here. :)

BTW your douglas ROM uses the stock kernel, right? For some reason the exploit doesn't leak the kernel pointer and fails the clobber test too. I tried this on douglas to see if we could get a software root again. Maybe a LineageOS thing, or an Amazon kernel thing...
[LG V20 Questions & Answers] Rortiz2:
Aight thanks.

About douglas, it uses custom kernel :P

The only thing is that is using it as prebuilt.

Here's the kernel source:

https://github.com/CM12-1-Douglas/android_kernel_amazon_douglas

Cheers!
[LG V20 Questions & Answers] DrZener:
If you have the sources for your kernel and the toolchain you can get offsets at compile time.
[LG V20 Questions & Answers] Rortiz2:
Ok good to know:)

With get them how you do that?
[LG V20 Questions & Answers] Supersonic27543:
Good to hear that, time to go back to FireOS :) Maybe the exploit would work on that kernel without modification. Thanks!
[LG V20 Questions & Answers] Rortiz2:
Well it's just an upstreamed kernel. Maybe the exploit was patched in some commit during the upstream.

Cheers!
[LG V20 Questions & Answers] DrZener:
Once you have a working building environment place a

BUILD_BUG_ON(offsetof(struct binder_thread, wait) < 0xSOMETHING )

And do a little of trial&error to find the SOMETHING value
[LG V20 Questions & Answers] Rortiz2:
Ok thanks. Last question sorry for being very dumb xD

Were I should place the BUILD_BUG_ON etc?

Thanks!
[LG V20 Questions & Answers] DrZener:
Somewhere in a function of binder.c
[LG V20 Questions & Answers] chompie1337:
The problem is that on a lot production firmwares SELinux cannot be set to permissive. See the attached pic from your firmware, SELinux will always be enforcing no matter what (get_selinux_enforcing always returns true). It is possible to load a custom SELinux policy where specific SELinux security contexts are permissive but it's more complicated than finding selinux_enforcing symbol and setting it to 0.
[LG V20 Questions & Answers] chompie1337:
when you import the file to IDA are you loading it as an android image? (see below). also you may need to fix kaslr. if you link the kernel image i can try to fix it for you.
[LG V20 Questions & Answers] chompie1337:
great! if i can make a suggestion - alot of us with 4.4 kernels have thread_info on the kstack. instead of querying kernel version, you could check the value of task_struct + 8 to see if it matches USER_DS (meaning that thread info is the first element of task_struct) otherwise search the kstack?
[LG V20 Questions & Answers] DrZener:
Do you mean by faking SS initialization status to force it reloading patched policies?
[LG V20 Questions & Answers] Supersonic27543:
Oh, that's too bad, but interesting as well. Do you know any other exploit/PoC with source that does something like that? It might be interesting to check how arbitrary kernel R/W is used to load a custom sepolicy (NVM if you know how it is done) and maybe it can be modified to work with this exploit :) Thanks!
[LG V20 Questions & Answers] chompie1337:
yes that is the technique i've seen. there could be other ways, that's my next step for research

i know how to create a custom sepolicy (sepolicy-inject has great code for that, i don't know the author off the top of my head so i apologize). actually loading it is tricky. but i have the same problem with my kernel so i'm working on a solution. probably won't work on it until tmrw tho.
[LG V20 Questions & Answers] Rortiz2:
I don't have that option :p
[LG V20 Questions & Answers] chompie1337:
make sure you have placed the vmlinux.py file here : C:\Program Files (x86)\IDA 6.9\loaders\vmlinux.py

sorry, the original instructions were for binja, i don't use IDA that much
[LG V20 Questions & Answers] Rortiz2:
Yes, is in there but still the same:)
[LG V20 Questions & Answers] arpruss:
Done. Yes, that's neater.
[LG V20 Questions & Answers] chompie1337:
not sure of the issue. if you can't find by compiling as suggested, you can post your firmware and i'll take a look for your offsets
[LG V20 Questions & Answers] arpruss:
Can we break kaslr by searching kernel memory for the version information in init_uts_ns?
[LG V20 Questions & Answers] chompie1337:
how do you mean? i think symbol offsets will change by build, especially if device manufacturer has added/removed any code
[LG V20 Questions & Answers] arpruss:
I was thinking that we search kernel memory for the version data in the symbol and we search kernel memory for the kallsyms tables. We then look up the symbol in the table, and the difference is the offset that breaks kaslr.

Or do devices with kaslr not have kallsyms tables?
[LG V20 Questions & Answers] chompie1337:
i think they do. right now the kernel search for kallsyms table doesn't work though. do you think that has to do with version? i think the ability to find one symbol would break KASLR yes because then the "slide" is known. you would have to know the relative offsets for the other symbols ahead of time though. is that what you mean? usually i just deal with KASLR by searching for signatures in memory, which is what it seems like you're already doing
[LG V20 Questions & Answers] arpruss:
Any idea why the memory search is failing? I don't have any 4.4 device myself.
[LG V20 Questions & Answers] chompie1337:
if i had to guess, because the search_base is being statically defined (not at the random kernel base) and the kallsyms table is located at a lower address