Start using build-time privapp whitelist checker

gf-arm64
FriendlyNeighborhoodShane 4 years ago
parent 23799f1a6f
commit 7f49166984

@ -89,6 +89,8 @@ You can pass build.sh a specific pack's conf name instead of all to build only t
If you have the Java SDK and openssl tool installed, the update script will dump the signing certificates of all downloaded APKs and repo jars to resdl/util/certs. It will compare all future downloads with those certs, and in case of any signature errors or mismatches, will warn you.
If you have aapt installed, the update script will download the permission docs from the Android website, check the priv-apps for any new privileged permissions and tell you to add them to the whitelist in res/system/etc/permissions/[package].xml files.
To build your own custom pack, refer to custom-pack.md in the conf directory.
### Credits

@ -1,200 +0,0 @@
createwhitelist() {
ui_print " ";
ui_print "Creating priv-app whitelist...";
spoofperm=android.permission.FAKE_PACKAGE_SIGNATURE;
spoofpermod=61006e00640072006f00690064002e007000650072006d0069007300730069006f006e002e00460041004b0045005f005000410043004b004100470045005f005300490047004e00410054005500520045;
hasspoof=false;
syslist="$filedir/privlist/privperm.list";
applist="$filedir/privlist/app.lst";
permlist="$filedir/privlist/app.xml";
unzip -oq "$zipfile" "privlist/*" -d "$filedir";
case "$arch" in
arm*)
aapt="$filedir/privlist/aapt-arm";
;;
x86*)
aapt="$filedir/privlist/aapt-x86";
;;
mips*)
aapt="$filedir/privlist/aapt-mips";
;;
esac;
[ -f "$aapt" ] || abort "No AAPT available";
chmod 777 "$aapt";
"$aapt" dump xmltree "/$sysroot/system/framework/framework-res.apk" AndroidManifest.xml | \
tr -d '\n' | sed -e 's/E:/\n/g' | grep '(type 0x11)0x[137]2' | \
awk -F\" '{print $2}' | sort > "$syslist";
unzip -oq "/$sysroot/system/framework/framework-res.apk" "AndroidManifest.xml" -d "$filedir/privlist/";
grep -qF "$spoofperm" "$filedir/privlist/AndroidManifest.xml" && hasspoof=true;
od -A n -t x1 "$filedir/privlist/AndroidManifest.xml" | tr -d ' \n' | grep -qF "$spoofpermod" && hasspoof=true;
if $hasspoof; then echo "android.permission.FAKE_PACKAGE_SIGNATURE" >> "${syslist}"; else log "WHITELISTER: No native sigspoof found"; fi;
buildlist() {
"${aapt}" dump permissions "$privobject" | \
awk -F \' '/^uses-permission:/{print $2}' | \
sort > "$applist";
[ "$(cat "$applist")" ] || return 1;
echo '<?xml version="1.0" encoding="utf-8"?>
<permissions>
<privapp-permissions package="'$package'">' > "$permlist";
for perm in $(cat "$applist"); do
if grep -q "$perm" "$syslist"; then
log "WHITELISTER: $package needs privapp-whitelist $perm";
echo ' <permission name="'$perm'" />' >> "$permlist";
fi;
done;
echo ' </privapp-permissions>
</permissions>' >> "$permlist";
}
unzip -oq "$zipfile" "system/priv-app/*" -d "$filedir";
for object in $stuff; do
case $object in
/system/priv-app/*/*.apk) ;;
*) continue;;
esac;
for realobject in $filedir/$object; do
privobject="$realobject"; break;
done;
[ -f "$privobject" ] || { log "ERROR: $privobject vanished"; continue; }
package="$("$aapt" dump badging "$privobject" | awk -F \' '/^package: name/{print $2}')";
log "WHITELISTER: Building list for $object";
buildlist || continue;
mkdir -p "$filedir/system/etc/permissions/";
mv -f "$permlist" "$filedir/system/etc/permissions/$package.xml";
stuff="$stuff
/system/etc/permissions/$package.xml
";
done;
for object in $stuff_arch; do
case $object in
/system/priv-app/*/*.apk) ;;
*) continue;;
esac;
for realobject in "$filedir/$(dirname "$object")"/*-"$arch"-*/"$(basename "$object")"; do
privobject="$realobject"; break;
done;
[ -f "$privobject" ] || { log "ERROR: $privobject vanished"; continue; }
package="$("$aapt" dump badging "$privobject" | awk -F \' '/^package: name/{print $2}')";
log "WHITELISTER: Building list for $object ($cond)";
cond="$(basename "$(dirname "$privobject")")";
buildlist;
mkdir -p "$filedir/system/etc/permissions/$cond/";
mv -f "$permlist" "$filedir/system/etc/permissions/$cond/$package.xml";
stuff_arch="$stuff_arch
/system/etc/permissions/$package.xml
";
done;
for object in $stuff_sdk; do
case $object in
/system/priv-app/*/*.apk) ;;
*) continue;;
esac;
for realobject in "$filedir/$(dirname "$object")"/*-"$sdk"-*/"$(basename "$object")"; do
privobject="$realobject"; break;
done;
[ -f "$privobject" ] || { log "ERROR: $privobject vanished"; continue; }
package="$("$aapt" dump badging "$privobject" | awk -F \' '/^package: name/{print $2}')";
cond="$(basename "$(dirname "$privobject")")";
log "WHITELISTER: Building list for $object ($cond)";
buildlist;
mkdir -p "$filedir/system/etc/permissions/$cond/";
mv -f "$permlist" "$filedir/system/etc/permissions/$cond/$package.xml";
stuff_sdk="$stuff_sdk
/system/etc/permissions/$package.xml
";
done;
for object in $stuff_arch_sdk; do
case $object in
/system/priv-app/*/*.apk) ;;
*) continue;;
esac;
for realobject in "$filedir/$(dirname "$object")"/*-"$arch"-*-"$sdk"-*/"$(basename "$object")"; do
privobject="$realobject"; break;
done;
[ -f "$privobject" ] || { log "ERROR: $privobject vanished"; continue; }
package="$("$aapt" dump badging "$privobject" | awk -F \' '/^package: name/{print $2}')";
cond="$(basename "$(dirname "$privobject")")";
log "WHITELISTER: Building list for $object ($cond)";
buildlist;
mkdir -p "$filedir/system/etc/permissions/$cond/";
mv -f "$permlist" "$filedir/system/etc/permissions/$cond/$package.xml";
stuff_arch_sdk="$stuff_arch_sdk
/system/etc/permissions/$package.xml
";
done;
}
getwhitelist() {
echo " ";
echo " - Getting priv-app permissions...";
privpermlist="util/privperms.lst";
privpermurl="https://developer.android.com/reference/android/Manifest.permission";
wget -q --show-progress "$privpermurl" -O "$tmpdir/tmppage" || { echo "ERROR: Android permission docpage failed to download" >&2; return 1; }
lines="$(grep -En "<!-- [=]* [A-Z ]* [=]* -->" "$tmpdir/tmppage" | grep -A1 "ENUM CONSTANTS DETAIL" | sed "s|:| |g" | awk '{ print $1 }')";
for line in $lines; do
[ "$startline" ] && endline="$line" || startline="$line";
done;
cat "$tmpdir/tmppage" | tail -n+"$(($startline + 1))" | head -n"$(($endline - $startline - 1))" | tr -d "\n" | sed "s|<div data|\n|g" | grep "Not for use by third-party applications" | grep -oE "android.permission.[A-Z_]*" > "$tmpdir/tmplist";
echo "android.permission.FAKE_PACKAGE_SIGNATURE" >> "$tmpdir/tmplist";
cat "$resdldir/$privpermlist" "$tmpdir/tmplist" | sort -u > "$tmpdir/sortedlist";
mv -f "$tmpdir/sortedlist" "$resdldir/$privpermlist";
}
checkwhitelist() {
echo " ";
echo " - Checking priv-app permissions...";
aapt="util/aapt";
privpermlist="util/privperms.lst";
[ -f "$resdldir/$privpermlist" ] || { echo "ERROR: No privileged permission list to check" >&2; return 1; }
[ -f "$resdldir/$aapt" ] || { echo "ERROR: No aapt found" >&2; return 1; }
privlogfile="$(ls -t $reldir/update-*.log | head)";
for privappfile in $(cat "$reldir/$privlogfile" | grep -Po "FILE: [^,]*" | cut -d" " -f2 | grep -o "/system/priv-app/.*/.*.apk"); do
[ -f "$privappfile" ] || { echo "ERROR: Privapp $privappfile not found" >&2; continue; }
privperms="";
privapppackage="$("$resdldir/$aapt" dump badging "$privappfile" | grep -o "package: name=[^ ]*" | sed "s|'| |g" | awk '{ print $3 }')"
privappperms="$("$resdldir/$aapt" dump permissions "$privappfile" | grep -o "uses-permission: name=[^ ]*" | sed "s|'| |g" | awk '{ print $3 }' | sort -u)";
for privperm in in $privappperms; do
grep -q "$privperm" "$resdldir/$privpermlist" || continue;
grep -q "$privperm" "$resdir/system/etc/permissions/$privapppackage.xml" && continue;
privperms="$privperm $privperms";
done;
[ "$privperms" ] || continue;
echo " ";
echo " -- File: $privappfile";
echo " -- Package: $privapppackage";
for permentry in $privperms; do
echo " ++ Needs whitelisting perm $permentry";
done;
done;
}

@ -71,6 +71,7 @@ post_update_actions() {
getzipsigner;
updatedelta;
verifycerts;
checkwhitelist;
return 0;
}
@ -192,3 +193,54 @@ verifycerts() {
done;
}
checkwhitelist() {
[ "$(which aapt)" ] || {
echo " ";
echo " !! Not checking privperms (missing aapt)";
return 0;
}
privpermlist="util/privperms.lst";
privpermurl="https://developer.android.com/reference/android/Manifest.permission";
echo " ";
echo " - Getting priv-app permissions...";
wget -q --show-progress "$privpermurl" -O "$tmpdir/tmppage" || { echo "ERROR: Android permission docpage failed to download" >&2; return 1; }
lines="$(grep -Pn "<!-- [=]* [A-Z ]* [=]* -->" "$tmpdir/tmppage" | grep -A1 "ENUM CONSTANTS DETAIL" | sed "s|:| |g" | select_word 1)";
for line in $lines; do
[ "$startline" ] && endline="$line" || startline="$line";
done;
cat "$tmpdir/tmppage" | tail -n+"$(($startline + 1))" | head -n"$(($endline - $startline - 1))" | tr -d "\n" | sed "s|<div data|\n|g" | grep "Not for use by third-party applications" | grep -oE "android.permission.[A-Z_]*" > "$tmpdir/tmplist";
echo "android.permission.FAKE_PACKAGE_SIGNATURE" >> "$tmpdir/tmplist";
cat "$resdldir/$privpermlist" "$tmpdir/tmplist" 2>/dev/null | sort -u > "$tmpdir/sortedlist";
mkdir -p "$resdldir/$(dirname "$privpermlist")"
mv -f "$tmpdir/sortedlist" "$resdldir/$privpermlist";
echo " ";
echo " - Checking priv-app permissions...";
for object in $(echo "$stuff_download" | grep -P "^[ \t]*/system/priv-app/[^ \t]+.apk[ \t]+" | select_word 1); do
[ -f "$resdldir/$object" ] || { echo "ERROR: Privapp $object not found" >&2; continue; }
privperms="";
privapppackage="$(aapt dump badging "$resdldir/$object" | grep -o "package: name=[^ ]*" | sed "s|'| |g" | select_word 3)"
privappperms="$(aapt dump permissions "$resdldir/$object" | grep -o "uses-permission: name=[^ ]*" | sed "s|'| |g" | select_word 3 | sort -u)";
for privperm in in $privappperms; do
grep -q "$privperm" "$resdldir/$privpermlist" || continue;
grep -q "$privperm" "$resdir/system/etc/permissions/$privapppackage.xml" 2>/dev/null && continue;
privperms="$privperm $privperms";
done;
[ "$privperms" ] || continue;
echo " ";
echo " -- File: $object";
echo " -- Package: $privapppackage";
for permentry in $privperms; do
echo " ++ Needs whitelisting perm $permentry";
done;
done;
}

@ -8,9 +8,10 @@
workdir="$(pwd)";
cd "$workdir" || { echo " "; echo "FATAL: Can't cd to $workdir"; return 1; };
confdir="$workdir/conf";
resdir="$workdir/res";
resdldir="$workdir/resdl";
reldir="$workdir/releases";
tmpdir="$workdir/tmp";
reldir="$workdir/releases";
updatetime="$(date -u +%Y%m%d%H%M%S)";
updatelog="$reldir/update-$updatetime.log";

Loading…
Cancel
Save