TL; DR: To pytanie dotyczy ostatniego kroku, w przenośnym, zorientowanym na programistów procesie rootowania, który działa na wszystkich urządzeniach z Androidem. Nie opiera się na żadnym exploicie - jest to coś, co jesteśmy prawnie i moralnie uprawnieni, jako programiści, do naszych własnych maszyn. Jeśli otrzymam odpowiedź i uda mi się chrootować w moim Debianie, opublikuję zwięzły post na blogu, szczegółowo opisujący wszystkie etapy tego procesu dla wszystkich programistów, którzy chcą dostępu do roota na swoich tabletach - i nie chcą ufać podejrzanemu pochodzeniu „root-one-click”, które wiedzą Bóg na swoich komputerach (członkowie botnetu?) ... Jedynymi zależnościami będą źródła jądra maszyny (które producent jest prawnie zobowiązany) oraz obraz partycji rozruchowej (boot.img
), co stanowi 99% przypadków w dostarczonych przez producenta aktualizacjach Over-The-Air lub osobno do pobrania jako samodzielny obraz z możliwością flashowania.
Minął tydzień, w którym spędziłem cały wolny czas na nowym tablecie z Androidem.
I prawie całkowicie odniosłem sukces - tworząc przenośny, zorientowany na programistów proces uzyskiwania uprawnień roota na moim tablecie z Androidem 5.0.2.
Ale brakuje jeszcze jednej rzeczy - nie mogę zrobić chroota (którego potrzebuję, aby uruchomić mój debootstrap
debian!)
Co zrobiłem do tej pory
- Najpierw zrobiłem drobną łatkę w źródłach jądra tabletu (dostarczonych przez producenta), a następnie skompilowałem własne jądro - w którym wyłączyłem sprawdzanie zmiany trybu wymuszania SELINUX . Konkretnie...
W security/selinux/selinuxfs.c
:
...
if (new_value != selinux_enforcing) {
/* Commented out by ttsiodras.
length = task_has_security(current, SECURITY__SETENFORCE);
if (length)
goto out;
*/
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
"enforcing=%d old_enforcing=%d auid=%u ses=%u",
new_value, selinux_enforcing,
Następnie zmieniłem obraz initrd
/default.prop
na zawierający:ro.secure=0
iro.debuggable=1
Ponieważ
initrd.img
brakowało mi tego producenta , skompilowałem równieżsu.c
z https://android.googlesource.com/platform/system/extras/+/master/su/ i umieściłem wynikowy plik binarny pod/sbin/su
, upewniając się, że jest ustawiony na SUID root (chmod 04755 /sbin/su
) .
Następnie spakowałem nowe jądro i nowy initrd, jak wyjaśniłem w odcinku 2 mojego poprzedniego postu - i uruchomiłem z własnego obrazu:
adb reboot boot-loader ; fastboot boot myboot.img
Więc jesteś rootem?
Tak, początkowo wydawało się sukcesem:
$ adb shell
shell@K01E_2:/ $ id
uid=2000(shell) gid=2000(shell) groups=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)
context=u:r:shell:s0
shell@K01E_2:/ $ ls -l /sbin/su /sbin/_su
-rwxr-xr-x root root 131 2015-10-03 10:44 su
-rwsr-xr-x root root 9420 2015-10-03 01:31 _su
(the _su is the binary I compiled, set to SUID root, and "su" is
a script I wrote to tell "su" to add me to all these groups...)
shell@K01E_2:/ $ cat /sbin/su
#!/system/bin/sh
export PATH=/system/bin:$PATH
exec /sbin/_su 0,0,1000,1028,2000,2001,1004,1007,1011,1015,\
1028,3001,3002,3003,3006
I teraz osiągnąłem root:
shell@K01E_2:/ $ su
root@K01E_2:/ # id
uid=0(root) gid=0(root)
groups=1000(system),1004(input),1007(log),1011(adb),
1015(sdcard_rw),1028(sdcard_r),1028(sdcard_r),2000(shell),2001(cache),
3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats)
context=u:r:shell:s0
Jestem w 100% pewien, że jestem rootem - nie tylko dlatego, id
że tak mówi, ale także dlatego, że mogę robić rzeczy, których normalne procesy zdecydowanie nie mogą:
root@K01E_2:/ # ls -l /dev/block/platform/msm_sdcc.1/by-name/boot
lrwxrwxrwx root root 2015-10-03 10:47 boot -> /dev/block/mmcblk0p16
root@K01E_2:/ # dd if=/dev/block/mmcblk0p16 of=/dev/null bs=1M
16+0 records in
16+0 records out
16777216 bytes transferred in 0.569 secs (29485441 bytes/sec)
I oto - w końcu mogę odczytać surowe partycje z mojego tabletu!
I SELinux rzeczywiście znajduje się w trybie „w dół, pies”:
root@K01E_2:/ # getenforce
Permissive
Ale ... wciąż są rzeczy, których nie mogę zrobić:
root@K01E_2:/ # mkdir /my_mnt
root@K01E_2:/ # mount -t ext4 /dev/block/mmcblk1p2 /my_mnt
mount: Operation not permitted
Oznacza to, że nie mogę zamontować drugiej partycji sformatowanej w EXT4-fs na mojej zewnętrznej karcie SD.
Nie mogę też chrootować do mojego uroczego debootstrap
Debiana:
root@K01E_2:/ # chroot /data/debian/ /bin/bash
chroot() fail
Operation not permitted
Czy to z powodu SELinuksa?
Nie wiem - jestem nowy (bardzo nowy - tydzień) w SELinux. Myślałem, że kiedy go uśpisz ( getenforce
raport „Permissive”), nie będzie już przeszkadzał ...
Najwyraźniej się myliłem. W dół króliczej nory znów idziemy ...
Czy może to wynikać z kontekstu mojego procesu?
Pamiętaj, że id
zwrócił ... "uid = 0 (root) gid = 0 (root) ... kontekst = u: r: shell: s0 "
Czy mogę zmienić ten kontekst? Będąc rootem, czy mogę odejść shell
? A jeśli tak, przejdź do czego?
Odpowiedź na pierwsze pytanie brzmi runcon
:
shell@K01E_2:/ $ runcon u:r:debuggerd:s0 /sbin/su
root@K01E_2:/ # id
uid=0(root) gid=0(root)... context=u:r:debuggerd:s0
Dobry. Ale w jakim kontekście pozwolę mount
i chroot
?
Czytając trochę więcej o SELinux, z powrotem na moim głównym komputerze, analizuję /sepolicy
plik w katalogu głównym initrd.img
:
linuxbox$ $ sesearch -A sepolicy | grep chroot
allow init_shell init_shell : capability { chown sys_chroot ...
allow init init : capability { chown dac_read_search sys_chroot ...
allow kernel kernel : capability { chown dac_override sys_chroot ...
allow asus-dbug-d asus-dbug-d : capability { chown sys_chroot ...
...
OK, wiele możliwości! Zwłaszcza, że kernel
wydaje się to obiecujące:
shell@K01E_2:/ $ runcon u:r:kernel:s0 /sbin/su
root@K01E_2:/ # id
uid=0(root) gid=0(root)... context=u:r:kernel:s0
root@K01E_2:/ # chroot /data/debian/ /bin/bash
chroot() fail
Operation not permitted
Cerować.
Kto do cholery mnie blokuje chroot
?
Wszelkie porady są mile widziane ...