The Problem
Investigators and red‑team operators often need to correlate a phone number with public data (carrier, code‑leak mentions, GitHub commits, etc.). Doing this manually requires juggling several APIs, handling rate limits, and stitching results into a readable report. The effort is repetitive and error‑prone, especially when a quick turnaround is needed during an engagement.
What This Does
SearchPhone is a single‑script Python utility that automates the OSINT workflow for a target phone number. The repository contains nine files; the core logic lives in search_phone.py, while requirements.txt lists the third‑party packages (e.g., phonenumbers, requests, pdfkit). The example.env file documents the required environment variables (NUMVERIFY_KEY, SERPAPI_KEY, GITHUB_TOKEN). Assets provide screenshot documentation, and the minimal CI folder only contains a funding manifest.
Running the script validates the number, queries Numverify for carrier data, issues parallel searches to Google (via SerpAPI), DuckDuckGo, GitHub code, and Reddit, and finally checks Hudson Rock’s “Cavalier” database for infostealer exposure. Results are emitted to the console with colorised output and saved as JSON + PDF reports.
How It Is Wired
Entry point – Execution starts at the bottom of search_phone.py, where a if __name__ == "__main__": guard calls a main() function (or equivalent).
Configuration – main() loads the .env file (via python-dotenv or os.getenv) to obtain the three required API keys. No external configuration parser is present.
External calls – Inside main(), the script invokes a series of helper functions, each wrapping a single third‑party API:
Helper (in search_phone.py) | External effect |
|---|---|
validate_number() | Uses phonenumbers (local validation, no network) |
numverify_lookup() | requests.get to numverify.com |
serpapi_search() | requests.get to serpapi.com (Google) |
duckduckgo_search() | requests.get to DuckDuckGo endpoints |
github_code_search() | requests.get to GitHub Search API (auth via token) |
reddit_search() | requests.get to Reddit API (no auth shown) |
hudsonrock_check() | requests.get to cavalier.hudsonrock.com (public) |
generate_report() | Writes JSON to disk, invokes pdfkit.from_string to create a PDF |
All of these functions are defined in the same file, making search_phone.py the sole hub of logic. Parallelism is achieved with concurrent.futures.ThreadPoolExecutor (or similar) that launches the API calls concurrently, then aggregates the dictionaries before passing them to the report generator. No other modules or packages are imported from the repository, so the script owns the entire side‑effect surface: network I/O, filesystem writes, and console rendering.
Because the code is monolithic, any change to request handling, error handling, or output formatting touches the same file, increasing the blast radius of modifications. No internal cycles are visible; the call graph is a shallow tree rooted at main().
How To Use It
# Clone the original repository (the fork is the source of this copy)
git clone https://github.com/moses-y/SearchPhone.git
cd SearchPhone
# Install Python dependencies
pip install -r requirements.txt
# Prepare API credentials
cp example.env .env
# Edit .env and set NUMVERIFY_KEY, SERPAPI_KEY, GITHUB_TOKEN
nano .env # or your preferred editor
# Run the tool
python3 search_phone.py
The script will prompt for a phone number (or accept one as a positional argument if implemented) and produce report_<number>.json and report_<number>.pdf in the current directory.
Real‑World Use
During a penetration test, a tester discovers a suspicious caller ID. By running search_phone.py +1‑202‑555‑0143, the tool instantly reveals that the number is registered to a known VoIP carrier (Numverify), appears in a recent GitHub commit leaking credentials, and has been flagged by Hudson Rock as associated with a known infostealer. The generated PDF can be attached to the client’s findings report without manual copy‑pasting.
Code Health & Issues
- Med – No test suite – No
tests/directory or pytest files; code paths are unverified. - Med – No CI/CD –
.githubonly contains aFUNDING.yml; no GitHub Actions or other pipelines. - Low – No lockfile – Dependencies are listed only in
requirements.txt; reproducible builds are not guaranteed.
No license file is missing (MIT present), and no secrets appear to be committed. Documentation consists of README.md and two screenshots; there is no API usage guide beyond the README.
The Bottom Line
SearchPhone delivers a functional, single‑file OSINT workflow for phone numbers, suitable for quick investigative scripts or as a prototype for larger tooling. Its simplicity is a strength for rapid adoption but a liability for maintainability: the monolithic design, lack of tests, and absent CI make it risky for production‑grade deployments. It is best used by security engineers comfortable reviewing and extending Python scripts, rather than by teams that require vetted, automated pipelines.