Debian on android shell
Goal: I had one old Android phone, with broken touching/gesture layer. One day, I found it on a dirty old place.
- I wonder how can I make it better with more usability.
- How can I make it work exactly as I needed.
- How can I transform this old phone to a super tiny linux machine with interactive shell?
Device: xiaomi Mi4W LTE, android 6.0.1 MMB29M
Specs: Qualcomm MSM8974PRO-AC Quad-core max 2.5GHz, 3.00 GB memory, 16GB disk
Kernel: 3.4.0-gf4b741d-00690-gc8911e
Arch: armv7l
Table of Contents
- A. Knowledge base
- B. Hacking / Practicing zone
- 1. Install adb and fastboot tools on mac
- 2. Download then install twrp & supersu on fastboot
- 3. Expand utilities with busybox
- 4. Config / fix env variables and configuations
- 5. Extract debian.img from available debian system (not BSD os like Mac)
- 6. Debootstrapping debian into android os
- 7. Complete debian os with apt and networking
- 8. Performance benchmarking
- C. Reference
A. Knowledge base
For accessing default android shell, we need adb
tools. For booting operation with custom image, we use fastboot
or adb reboot recovery
.
After accessing, with twrp
and supersu
we can grant root
privileges because we need root permission for doing mount
filesystem and totally control the whole system.
We also need busybox
for expanding utilities like editing files by vi
, checking network connection, …
It’s done for controlling android via adb shell
, but currently, linux os on android is designed for mobile, apk applications, everyday carry and easy to use for all kinds of users, also it’s not using any kind of package management like apt
or yum
, I nearly can do nothing on current system.
From devops/sre point of view, all I want is pushing/booting a fully linux
os to my android, that’s I can do more things on this, instead of limited android os.
I decided to use debian stretch
with debootrap
for extract custom image and init debian filesystem via chroot
to current android sdcard
directory.
B. Hacking / Practicing zone
1. Install adb and fastboot tools on mac
mac❯❯ brew cask install android-platform-tools
mac❯❯ adb --version
Android Debug Bridge version 1.0.40
Version 4797878
Installed as /usr/local/bin/adb
mac❯❯ fastboot --version
fastboot version 28.0.0-4797878
Installed as /usr/local/bin/fastboot
# Connect android to mac via usb
# Verify device
mac❯❯ adb devices -l
List of devices attached
1f703708 device usb:336592896X product:cancro_wc_lte model:MI_4W device:cancro transport_id:13
2. Download then install twrp & supersu on fastboot
mac❯❯ wget internet.com/SR5-SuperSU-v2.82-SR5-20171001224502.zip ./
mac❯❯ wget internet.com/twrp-3.1.0-0-cancro.img ./
mac❯❯ adb push ./SR5-SuperSU-v2.82-SR5-20171001224502.zip /storage/self/primary/
SR5-SuperSU-v2.82-SR5-20171001224502.zip: 1 file pushed. 5.8 MB/s (6882992 bytes in 1.127s)
mac❯❯ adb reboot bootloader
mac❯❯ fastboot devices
1f703708 fastboot
mac❯❯ fastboot flash recovery ./twrp-3.1.0-0-cancro.img
Sending 'recovery' (13682 KB) OKAY [ 0.464s]
Writing 'recovery' OKAY [ 0.305s]
Finished. Total time: 0.772s
mac❯❯ fastboot boot ./twrp-3.1.0-0-cancro.img
Downloading 'boot.img' OKAY [ 0.432s]
booting OKAY [ 0.119s]
Finished. Total time: 0.560s
# After booted into TWRP
# Install SR5-SuperSU-v2.82-SR5-20171001224502.zip from TWRP
# Do it on touch screen, or via twrp commandline
mac❯❯ adb shell
android❯❯ twrp install /storage/self/primary/SR5-SuperSU-v2.82-SR5-20171001224502.zip
android❯❯ twrp wipe cache
android❯❯ reboot
# Verify root on device
mac❯❯ adb shell
shell@cancro:/ $ su -
root@cancro:/ # whoami
root
3. Expand utilities with busybox
mac❯❯ wget https://busybox.net/downloads/binaries/1.28.1-defconfig-multiarch/busybox-armv7l
mac❯❯ adb push busybox-armv7l /data/local/tmp
busybox-armv7l: 1 file pushed. 3.8 MB/s (1079156 bytes in 0.270s)
mac❯❯ adb shell
shell@cancro:/ $ su -
root@cancro:/ # mkdir /data/busybox
root@cancro:/ # move /data/local/tmp/busybox-armv7l /data/busybox
root@cancro:/ # cd /data/busybox
root@cancro:/data/busybox # ls -l
-rwxrwxrwx shell shell 1079156 2018-02-15 20:47 busybox-armv7l
root@cancro:/data/busybox # ./busybox-armv7l --install ./
# Use ls of busybox
# instead of current ls on android
root@cancro:/ # which ls
/system/bin/ls
root@cancro:/ # export PATH=/data/busybox:$PATH
root@cancro:/ # which ls
/data/busybox/ls
root@cancro:/ # which vi
/data/busybox/vi
4. Config / fix env variables and configuations
# Choose one: (for security mount /system back to RO when finished)
# Mount system RW: mount -o rw,remount /system
# Mount system RO: mount -o ro,remount /system
root@cancro:/ # mount -o rw,remount /system
root@cancro:/ # vi /system/etc/mkshrc
...
export PATH=/data/busybox:$PATH
...
when facing with su command like this, we need reconfigure su
# Issue with su command
shell@cancro:/ $ su
su: must be suid to work properly
# Resolve
root@cancro:/ # cp /su/bin/su /data/busybox/su
root@cancro:/ # ls -lh /su/bin/su
-rwxr-xr-x 1 0 0 73.6K Sep 11 13:49 /su/bin/su
root@cancro:/ # ls -lh /data/busybox/su
-rwx------ 1 0 0 73.6K Sep 11 15:58 /data/busybox/su
5. Extract debian.img from available debian system (not BSD os like Mac)
Install debootstrap then bootstrapping debian stretch image for armv7l arch
debian❯❯ apt install -y debootstrap debian-archive-keyring debian-ports-archive-keyring
debian❯❯ mkdir debian-armhf
debian❯❯ cd debian-armhf/
debian❯❯ dd if=/dev/zero of=debian.img bs=1MiB count=2000
debian❯❯ mke2fs -F debian.img
debian❯❯ mkdir debian
debian❯❯ mount -o loop debian.img debian
debian❯❯ debootstrap --arch armhf --foreign --verbose stretch debian http://ftp.us.debian.org/debian
debian❯❯ umount debian
rsync file debian.img from debian system to mac system, then push this img to android
mac❯❯ adb push debian.img /sdcard/
6. Debootstrapping debian into android os
mac❯❯ adb shell
shell@cancro:/ $ su -
root@cancro:/ # mkdir /sdcard/debian-stretch9
root@cancro:/ # losetup /dev/block/loop99 /sdcard/debian.img
root@cancro:/ # mount /dev/block/loop99 /sdcard/debian-stretch9
root@cancro:/ # chroot /sdcard/debian-stretch9 /bin/bash
export PATH=/usr/bin:/usr/sbin:/bin:$PATH
export TERM=linux
export HOME=/root
export USER=root
/debootstrap/debootstrap --second-stage
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
echo "127.0.0.1 localhost" > /etc/hosts
exit
mac❯❯ adb shell
shell@cancro:/ $ su -
root@cancro:/ # chroot /sdcard/debian-stretch9 /bin/su - root
root@localhost:~# whoami #should be root
root@localhost:~# cat /etc/debian_version #9.5
7. Complete debian os with apt and networking
From the first time, I cannot use ping
or apt
, because Android uses a special Kernel patch that’s activated with CONFIG_ANDROID_PARANOID_NETWORK
.
For adding specific groups, this patch allows network access to system users that belong to certain special groups with hardcoded IDs.
mac❯❯ adb shell
shell@cancro:/ $ su -
root@cancro:/ # chroot /sdcard/debian-stretch9/ /bin/su - root
root@localhost:~# groupadd -g 3001 aid_bt
root@localhost:~# groupadd -g 3002 aid_bt_net
root@localhost:~# groupadd -g 3003 aid_inet
root@localhost:~# groupadd -g 3004 aid_net_raw
root@localhost:~# groupadd -g 3005 aid_admin
root@localhost:~# usermod -a -G aid_bt,aid_bt_net,aid_inet,aid_net_raw,aid_admin root
exit - relogin
root@localhost:~# grep -E "_apt" /etc/passwd
_apt:x:104:65534::/nonexistent:/bin/false
root@localhost:~# usermod -g 3003 _apt
root@localhost:~# grep -E "_apt" /etc/passwd
_apt:x:104:3003::/nonexistent:/bin/false
root@localhost:~# apt update
Ign:1 http://ftp.de.debian.org/pub/debian stable InRelease
Get:2 http://ftp.de.debian.org/pub/debian stable Release [118 kB]
...
Fetched 12.7 MB in 36s (351 kB/s)
Reading package lists... Done
Building dependency tree... Done
All packages are up to date.
8. Performance benchmarking
…to be continue