-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathfsp
157 lines (139 loc) · 6.42 KB
/
fsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env bash
# FireStorePwn
# Color variables
resetColor="\e[0m"
redColor="\e[31m"
greenColor="\e[32m"
yellowColor="\e[33m"
magentaColor="\e[35m"
cyanColor="\e[36m"
echo -e "${magentaColor} _____
_/ ____\____________ ${cyanColor}FireStorePwn${magentaColor}
\ __\/ ___/\____ \
| | \___ \ | |_> > ${cyanColor}Firestore Database Vulnerability Scanner Using APKs${magentaColor}
|__| /____ >| __/
\/ |__| ${cyanColor}by Víctor García (@takito1812)${resetColor}
"
checkTool() {
if ! dpkg -l "$1" >/dev/null 2>&1; then
echo -e "${yellowColor}[!] Installing $1...${resetColor}\n"
apt-get update -y >/dev/null 2>&1
apt-get install "$1" -y >/dev/null 2>&1
fi
}
quit() {
rm -rf "$filename"
exit
}
checkCollections() {
echo
if [[ "$1" ]]; then
token="$1"
if echo "$1" | grep -q ":"; then
if ! apiKey=$(grep -i "google_api_key" "$filename/res/values/strings.xml"); then
echo -e "${redColor}[-] google_api_key not found in res/values/strings.xml file.${resetColor}"
quit
else
echo -e "${greenColor}[+] google_api_key found in res/values/strings.xml file:${resetColor}"
apiKey=$(echo "$apiKey" | sed -n 's:.*<string name="google_api_key">\(.*\)</string>.*:\1:pI')
echo -e "$apiKey\n"
fi
email=$(echo "$1" | cut -d: -f1)
password=$(echo "$1" | cut -d: -f2)
token=$(curl -s -X POST -H "Content-Type: application/json" -d "{
'email':'$email',
'password':'$password',
'returnSecureToken':true
}" "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=$apiKey" | jq -r '.idToken')
if [[ "$token" == "null" ]]; then
echo -e "${redColor}[-] Failed to get an authentication token.${resetColor}"
quit
else
echo -e "${greenColor}[+] It was possible to obtain an authentication token:${resetColor}\n$token\n"
fi
fi
declare -a authHeader=('-H' "Authorization: Bearer $token")
fi
for c in "${collections[@]}"; do
outputReadable=$(curl "${authHeader[@]}" -s "https://firestore.googleapis.com/v1beta1/projects/$projectID/databases/(default)/documents/$c")
if echo "$outputReadable" | grep -q '"error":'; then
echo -e "${redColor}[-] The collection $c is not readable.${resetColor}"
else
echo -e "${greenColor}[+] The collection $c is readable:${resetColor}\n$outputReadable"
fi
outputWritable=$(curl "${authHeader[@]}" -X POST -s "https://firestore.googleapis.com/v1/projects/$projectID/databases/(default)/documents/$c" -H "Content-Type: application/json" -d '{
"fields": {
"fspPoC": {
"stringValue": "writable"
},
}
}')
if echo "$outputWritable" | grep -q '"error":'; then
echo -e "${redColor}[-] The collection $c is not writable.${resetColor}"
else
echo -e "${greenColor}[+] The collection $c is writable:${resetColor}\n$outputWritable"
writtenCollectionID=$(echo "$outputWritable" | jq -r '.name' | rev | cut -d'/' -f 1 | rev)
sleep 2
curl "${authHeader[@]}" -X DELETE -s "https://firestore.googleapis.com/v1beta1/projects/$projectID/databases/(default)/documents/$c/$writtenCollectionID"
fi
echo
done
}
checkTool "apktool"
checkTool "jq"
if [[ -f "$1" ]]; then
filename=$(basename -- "$1")
extension="${filename##*.}"
filename="fsp-${filename%.*}"
if [[ "$extension" == "apk" ]]; then
echo -e "${yellowColor}[!] The specified APK is $1.${resetColor}\n"
if apktool d "$1" -o "$filename" >/dev/null 2>&1; then
echo -e "${greenColor}[+] Successful decompilation with apktool.${resetColor}\n"
else
echo -e "${redColor}[-] Decompilation failed with apktool.${resetColor}"
quit
fi
if ! grep -qi "firebase" "$filename/AndroidManifest.xml"; then
echo -e "${redColor}[-] Firebase not found in the AndroidManifest.xml${resetColor}"
quit
else
echo -e "${greenColor}[+] Firebase found in the AndroidManifest.xml${resetColor}\n"
if ! projectID=$(grep -i "project_id" "$filename/res/values/strings.xml"); then
echo -e "${redColor}[-] project_id not found in res/values/strings.xml file.${resetColor}"
quit
else
echo -e "${greenColor}[+] project_id found in res/values/strings.xml file:${resetColor}"
projectID=$(echo "$projectID" | sed -n 's:.*<string name="project_id">\(.*\)</string>.*:\1:pI')
echo -e "$projectID\n"
matchString="lcom/google/firebase/firestore/FirebaseFirestore"
for c in $(grep -hA 2 "$matchString" -irw "$filename"/smali* 2>/dev/null | grep -iv "$matchString" | grep const-string | sed 's/[^"]*"\([^"]*\)".*/\1/' | sort -u | sed 's/Provided data must not be null.//g'); do
collections+=("$c")
done
if [ "${#collections[@]}" -eq 0 ]; then
echo -e "${redColor}[-] No collections found in .smali files.${resetColor}"
quit
else
echo -e "${greenColor}[+] ${#collections[@]} Collection(s) found in .smali files.${resetColor}"
for c in "${collections[@]}"; do
echo "$c"
done; echo
echo -e "${yellowColor}[!] IMPORTANT: Consulting collections can have an economic impact on the objective."
echo -e " Firestore has a daily expense depending on the number of operations performed.${resetColor}\n"
while true; do
read -rp "[!] Do you want to check the permissions of these collections anyway? [y/n] " yn
case "$yn" in
[Yy]* ) checkCollections "$2"; quit;;
[Nn]* ) quit;;
* ) echo -e "\n${yellowColor}[!] Please answer yes or no.${resetColor}\n";;
esac
done
fi
fi
fi
else
echo -e "${redColor}[-] The specified file does not have an .apk extension.${resetColor}"
quit
fi
else
echo -e "${yellowColor}[!] Usage: $(basename "$0") <APKFILE> [CREDS/TOKEN]${resetColor}"
fi