Skip to content

Instantly share code, notes, and snippets.

@mr-fixit
Last active March 22, 2021 18:45
Show Gist options
  • Save mr-fixit/5db589ba7f5f7028aba65fc7c9731370 to your computer and use it in GitHub Desktop.
Save mr-fixit/5db589ba7f5f7028aba65fc7c9731370 to your computer and use it in GitHub Desktop.
#!/bin/bash
# scan path[s] for files, folders or ZIPs containing Xcode projects with suspicious contents
if [[ $# == 0 ]]; then
echo "usage: $0 [--verbose] path [path2 ...]"
echo " path can be a folder or a file"
exit
fi
function do_file() {
FILE=$1
if [[ -z $QUIET ]]; then
echo "do_file(): '${FILE}'"
fi
FILE_TYPE=`file -b --mime "$FILE"`
if [[ $FILE_TYPE =~ "application/gzip" ]]; then
echo "error: $0 doesn't do gzip files like $FILE"
elif [[ $FILE_TYPE =~ "application/zip" ]]; then
# echo the path on any line containing pbxproj by JMPing over the first 3 fields
unzip -l "$FILE" | \
awk '/pbxproj/ {JMP=3; for (i=1; i<=NF-JMP; i++) $i = $(i+JMP); NF-=JMP; print}' | \
while read PBX_INTERNAL_PATH; do
if [[ -z $QUIET ]]; then
echo "project path in zip file: '$PBX_INTERNAL_PATH'"
fi
TMP_PROJECT=`mktemp`
unzip -p "$FILE" "$PBX_INTERNAL_PATH" > $TMP_PROJECT
do_project $TMP_PROJECT "$FILE"
done
elif [[ "$FILE" =~ ".pbxproj" ]]; then
do_project "$FILE"
elif [[ -z $QUIET ]]; then
echo \'$FILE\' is not a ZIP file
fi
}
function do_project() {
PBXPROJ="$1"
ZIPFILE="$2"
# look for any hidden files
grep $QUIET '/\.[^.]' "$PBXPROJ"
no_hidden=$?
# look for XCSSET malware
grep $QUIET xcuserdata/.xcassets/Assets.xcassets "$PBXPROJ"
no_xcsset=$?
# look for 'eval' in build phases
grep 'shellScript.*eval' "$PBXPROJ"
no_eval=$?
# report
if [[ -s "$ZIPFILE" ]]; then
IN_ZIP=" in ${ZIPFILE}"
fi
if (( ! $no_xcsset )); then
echo " ${PBX_INTERNAL_PATH}${IN_ZIP} is infected with XCSSET malware"
fi
if (( ! $no_hidden )); then
echo " ${PBX_INTERNAL_PATH}${IN_ZIP} references hidden files"
fi
if (( ! $no_eval )); then
echo " ${PBX_INTERNAL_PATH}${IN_ZIP} contains eval expressions in shell-script build phases (see above)"
fi
if (( $no_xcsset | ! $no_hidden | ! $no_eval )); then
echo " ${PBX_INTERNAL_PATH}${IN_ZIP} appears to be OK"
fi
}
QUIET=-q
for PARAM in "$@"; do
if [[ $PARAM = --verbose ]]; then QUIET=""; continue; fi
if [[ -z $QUIET ]]; then
echo "PARAM='${PARAM}'"
fi
find "${PARAM}" -type f | while read FILE; do do_file "${FILE}"; done
done
@mr-fixit
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment