Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 74 additions & 28 deletions key_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import tempfile
import re
import pyfiglet
import argparse

def print_banner():
main_banner = pyfiglet.figlet_format("Privia Security")
sub_banner = pyfiglet.figlet_format("Key Detector")
print(main_banner)
print(sub_banner)

def decompile_apk(apk_path, output_dir):
"""\033[33m[!] Decompile the APK \033[0m"""
try:
Expand All @@ -20,57 +21,102 @@ def decompile_apk(apk_path, output_dir):
sys.exit(1)

def is_variable_definition(line, keyword):
"""\033[33m[!] Check if a line contains a variable definition with the given keyword.\033[0m"""

variable_pattern = re.compile(rf"\b\w*{re.escape(keyword)}\w*\b\s*=.*", re.IGNORECASE)
"""Check if a line contains a variable definition with the given keyword."""
variable_pattern = re.compile(
rf"\b(?:[a-zA-Z_]\w*\s+)?\w*{re.escape(keyword)}\w*\b\s*=\s*.+",
re.IGNORECASE
)
return bool(variable_pattern.search(line))

def search_keywords_in_files(directory, keywords):
"""\033[33m[!] Search for multiple keywords in all files within a directory and check if they are variables.\033[0m"""
"""Search for multiple keywords in all files within a directory and check if they are variables."""
matches = {keyword: [] for keyword in keywords}
total_files = sum([len(files) for _, _, files in os.walk(directory)])
files_processed = 0
reported_lines = set()

for root, _, files in os.walk(directory):
for file in files:
file_path = os.path.join(root, file)
try:
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
for line_no, line in enumerate(f, start=1):
for keyword in keywords:
if is_variable_definition(line, keyword):
matches[keyword].append((file_path, line_no, line.strip()))
if (file_path, line_no) not in reported_lines:
if is_variable_definition(line, keyword):
matches[keyword].append((file_path, line_no, line.strip()))
print(f"\033[32m[+] File Found:\033[0m {file_path}, Line: {line_no}, \033[32;1m [+] Match Value: {line.strip()}\033[0m", flush=True)
reported_lines.add((file_path, line_no))
except Exception as e:
print(f"\033[31mCould not read {file_path}: {e}\033[0m")
print(f"Could not read {file_path}: {e}")

files_processed += 1
print(f"Searching files: {files_processed}/{total_files} files processed...", end="\r", flush=True)

return matches

def load_keywords_from_file(wordlist_path):
"""Load keywords from a wordlist file."""
try:
with open(wordlist_path, "r", encoding="utf-8") as f:
keywords = [line.strip() for line in f.readlines() if line.strip()]
return keywords
except Exception as e:
print(f"Error loading wordlist file: {e}")
sys.exit(1)

def extract_and_search_apk(apk_path, keywords):
"""\033[33m [!] Extract APK contents and search for multiple keywords as variables.\033[0m"""
"""Extract APK contents and search for multiple keywords as variables."""
with tempfile.TemporaryDirectory() as temp_dir:

print("\033[33m [!] Decompiling the APK...\033[0m")
print("Decompiling the APK...")
decompiled_dir = os.path.join(temp_dir, "decompiled")
decompile_apk(apk_path, decompiled_dir)

print(f"\033[33m[!] Searching for keywords as variables: {', '.join(keywords)}...\033[0m")
print(f"Starting to Search for keywords")
matches = search_keywords_in_files(decompiled_dir, keywords)

matches_found = any(len(match) > 0 for match in matches.values())

if not matches_found:
print("\033[31m[-] No matches found.\033[0m")

for keyword, occurrences in matches.items():
print(f"\n\033[32m[+] Results for keyword '{keyword}':\033[0m")
if occurrences:
for match in occurrences:
print(f"\033[32m[+] File Found:\033[0m {match[0]}, Line: {match[1]}, \033[32;1m [+] Match Value: {match[2]}\033[0m")
else:
print("\033[31m[-] No matches found.\033[0m")
def main():
parser = argparse.ArgumentParser(
description="APK Key Detector - A tool to detect keywords in APK files, either by direct input or using a wordlist.",
usage="python %(prog)s apk_file \"keyword1,keyword2\" or python %(prog)s apk_file -w wordlist.txt"
)
parser.add_argument("apk_file", help="Path to the APK file to be scanned.")
parser.add_argument(
"-w",
"--wordlist",
help="Path to a wordlist file containing keywords to search for.",
default=None,
)
parser.add_argument(
"keywords",
nargs="?",
help="Comma-separated list of keywords to search directly (used when --wordlist is not provided).",
default=None,
)

if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python apk_reverse_search.py <apk_file_path> <comma_separated_keywords>")
args = parser.parse_args()

if not os.path.isfile(args.apk_file):
print(f"File not found: {args.apk_file}")
sys.exit(1)

apk_file_path = sys.argv[1]
keywords = sys.argv[2].split(',')
print_banner()

if not os.path.isfile(apk_file_path):
print(f"File not found: {apk_file_path}")
if args.wordlist:
keywords = load_keywords_from_file(args.wordlist)
print(f"{len(keywords)} keywords loaded from wordlist.")
elif args.keywords:
keywords = args.keywords.split(',')
else:
print("Error: You must provide either a wordlist or keywords.")
sys.exit(1)

print_banner()
extract_and_search_apk(apk_file_path, keywords)
extract_and_search_apk(args.apk_file, keywords)

if __name__ == "__main__":
main()
152 changes: 152 additions & 0 deletions seclist-env-wordlist.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AMAZON_AWS_ACCESS_KEY_ID
AMAZON_AWS_SECRET_ACCESS_KEY
ALGOLIA_API_KEY
AZURE_CLIENT_ID
AZURE_CLIENT_SECRET
AZURE_USERNAME
AZURE_PASSWORD
MSI_ENDPOINT
MSI_SECRET
binance_api
binance_secret
BITTREX_API_KEY
BITTREX_API_SECRET
CF_PASSWORD
CF_USERNAME
CODECLIMATE_REPO_TOKEN
COVERALLS_REPO_TOKEN
CIRCLE_TOKEN
DIGITALOCEAN_ACCESS_TOKEN
DOCKER_EMAIL
DOCKER_PASSWORD
DOCKER_USERNAME
DOCKERHUB_PASSWORD
FACEBOOK_APP_ID
FACEBOOK_APP_SECRET
FACEBOOK_ACCESS_TOKEN
FIREBASE_TOKEN
FIREBASE_API_TOKEN
FOSSA_API_KEY
GH_TOKEN
GH_ENTERPRISE_TOKEN
CI_DEPLOY_PASSWORD
CI_DEPLOY_USER
GOOGLE_APPLICATION_CREDENTIALS
GOOGLE_API_KEY
ONE_SIGNAL_REST_API_KEY
CI_DEPLOY_USER
CI_DEPLOY_PASSWORD
GITLAB_USER_LOGIN
CI_JOB_JWT
CI_JOB_JWT_V2
CI_JOB_TOKEN
HEROKU_API_KEY
HEROKU_API_USER
MAILGUN_API_KEY
MCLI_PRIVATE_API_KEY
MCLI_PUBLIC_API_KEY
NGROK_TOKEN
NGROK_AUTH_TOKEN
NPM_AUTH_TOKEN
OKTA_CLIENT_ORGURL
OKTA_CLIENT_TOKEN
OKTA_OAUTH2_CLIENTSECRET
OKTA_OAUTH2_CLIENTID
OKTA_AUTHN_GROUPID
OS_USERNAME
OS_PASSWORD
PERCY_TOKEN
POSTGRES_PASSWORD
SAUCE_ACCESS_KEY
SAUCE_USERNAME
SENTRY_AUTH_TOKEN
SLACK_TOKEN
square_access_token
square_oauth_secret
STRIPE_API_KEY
STRIPE_DEVICE_NAME
SURGE_TOKEN
SURGE_LOGIN
TWILIO_ACCOUNT_SID
CONSUMER_KEY
CONSUMER_SECRET
TRAVIS_SUDO
TRAVIS_OS_NAME
TRAVIS_SECURE_ENV_VARS
TELEGRAM_BOT_TOKEN
VAULT_TOKEN
VAULT_CLIENT_KEY
TOKEN
VULTR_ACCESS
VULTR_SECRET
ConsumerKey
ConsumerSecret
DB_USERNAME
HEROKU_API_KEY
HOMEBREW_GITHUB_API_TOKEN
JEKYLL_GITHUB_TOKEN
PT_TOKEN
SESSION_TOKEN
SF_USERNAME
SLACK_BOT_TOKEN
access-token
access_token
access_token_secret
accesstoken
admin
api-key
api_key
api_secret_key
api_token
auth_token
authkey
authorization
authorization_key
authorization_token
authtoken
aws_access_key_id
aws_secret_access_key
bearer
bot_access_token
bucket
client-secret
client_id
client_key
client_secret
clientsecret
consumer_key
consumer_secret
dbpasswd
email
encryption-key
encryption_key
encryptionkey
id_dsa
irc_pass
key
oauth_token
pass
password
private_key
private-key
privatekey
secret
secret-key
secret_key
secret_token
secretkey
secretkey
session_key
session_secret
slack_api_token
slack_secret_token
slack_token
ssh-key
ssh_key
sshkey
token
username
xoxa-2
xoxr