References
TL;TR
- install prerequisites
- create the script
nop.sh
- extract
adbd
from initial ramdisk
-
patch adbd
./nop.sh adbd "4f f4 fa 60 0e f0 86 ed 00 28 df d1 4f f4 fa 60 16 f0 47 f8 00 28 d9 d1" && \
cat adbd.patched > adbd && rm adbd.patched
./nop.sh adbd '0e f0 de ed' && \
cat adbd.patched > adbd && rm adbd.patched
-
recreate boot.img
-
test and flash via fastboot
Prerequisites
-
I’m working on Ubuntu 21.10, so I’ve to install these packages
apt install abootimg openjdk-11-jdk
-
We are going to patch a binary file, so we have to use a disassembler: Ghidra
Procedure
Extract the adbd
binary from Tolino firmware update file
-
download the right version of your update (for me it’s currently 14.1.0)
wget https://download.pageplace.de/ereader/14.1.0/alldevices/update.zip
(as a sidenote, you can find the latest tolino update on the Tolino website)
-
extract boot.img
unzip update.zip boot.img
-
unpack boot.img
(we need the initial ramdisk initrd.img
)
abootimg -x boot.img
-
extract the ramdisk in a directory
mkdir ramdisk
zcat initrd.img | ( cd ramdisk/ && cpio -imd )
You’ll find adbd
in this path ramdisk/sbin/adbd
.
Setup disassembler (Ghidra)
-
open Ghidra and select File
, New Project...
, Next
, choose a directory for the project and give it a name
-
click on CodeBrowser
(it’s a green dragon)
-
File
, Import File...
and navigate in the previous ramdisk/
folder, under ramdisk/sbin/
and choose adbd
-
go on and select all the possible analysis checkboxes, then Analyze
Find all the interesting functions
When the Tolino starts adbd
is not activated. We can enable it, (following these steps), but it will run under uid=2000 and git=2000 (no root
).
If you inspect the source code, you’ll see that there are some references to functions related to users/groups/capabilities:
setuid(2000)
setgid(2000)
prctl(PR_CAPBSET_DROP, ...)
We need to inhibit those calls.
Patch setuid
and setgid
The first 2 functions are called as shown below (AID_SHELL
is 2000
, full code here):
gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
AID_MOUNT, AID_NET_BW_STATS };
if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
exit(1);
}
/* then switch user and group to "shell" */
if (setgid(AID_SHELL) != 0) {
exit(1);
}
if (setuid(AID_SHELL) != 0) {
exit(1);
}
D("Local port disabled\n");
Under Ghidra search for 0x7d0
(200010) using Search
, Program Text
. Choose Instruction Operands
and Search All
. You should see something like this
The first 2 occurences are near each other. Here’s in the code browser
We can translate it as
So it would be great to replace all the highlighted part with nop
(no operation instruction in assembler).
I created this simple script just to do it (nop.sh
):
#!/bin/bash
set -e
if [[ $# -ne 2 ]]; then
echo "Usage:"
echo " $(basename "$0") <file> <hex string>"
exit 1
fi
input="$1"
hex="$(tr -d ' :' <<< "$2")"
output="$input.patched"
# build a nop string, the same size of "hex"
nops="$(printf "%*s" $(( ${#hex} / 4)) '' | sed 's: :00bf:g')"
# patch and rebuild binary
xxd -ps "$input" | tr -d '\n' | sed "s:$hex:$nops:g" | xxd -r -p > "$output"
# confirm substitution
[[ $(md5sum <"$input") != "$(md5sum <"$output")" ]] || { echo "$(basename "$0"): [WARNING] nothing done" >&2; exit 2; }
# check file size
[[ $(stat -c%s "$input") = $(stat -c%s "$output") ]] || { echo "$(basename "$0"): [ERROR] size mismatch" >&2; exit 3; }
echo "$output done"
Open the binary view under Windows
, Bytes
and select the block of code. In the Bytes
window copy the highlighted bytes and do this
./nop.sh adbd "4f f4 fa 60 0e f0 86 ed 00 28 df d1 4f f4 fa 60 16 f0 47 f8 00 28 d9 d1"
cat adbd.patched > adbd
rm adbd.patched
Patch prctl(PR_CAPBSET_DROP, ...)
Then we have to remove prctl(PR_CAPBSET_DROP, ...)
.
The code is right after ADB_EXTERNAL_STORAGE
Translated to
It’s sufficient to remove the call 0e f0 de ed
./nop.sh adbd '0e f0 de ed'
cat adbd.patched > adbd
rm adbd.patched
This adbd
will run with root
privileges, but we have to set up the boot.img
accordingly. Copy the file as shown and follow these steps.
cp adbd /tmp/adbd.patched