Favicon similarity scanner powered by local vision models via Ollama. favlens compares site favicons against a base reference and reports matches, helping you expand your attack surface to find sites with similar or identical favicons.
This is a recon-focused utility that helps validate which assets belong to your targets by using AI vision to find favicon and logo similarities across domains. It supports asset discovery, brand mapping, and reduces false positives through image-based matching.
- Concurrent workers for faster scans on large URL lists
- Flexible logging modes: debug, verbose, and silent
- Save matched URLs to a file for downstream processing
- Go 1.21+
- Ollama installed and running (https://ollama.com/)
- A vision-capable Ollama model available locally (examples:
gemma3:4b,llava:7b,moondream,bakllava)
Example to pull a model:
ollama pull gemma3:4b
go install -v github.com/ethicalhackingplayground/favlens/v2/cmd/favlens@latest
On Windows, the binary will be favlens.exe.
Basic usage:
favlens -base https://example.com/favicon.ico -file urls.txt
CLI flags:
-basestring
Base favicon URL to compare against (required)-debug
Enable debug logging (shows everything)-delayint
Delay between requests in milliseconds (default: 0)-filestring
Path to file containing URLs to check (required)-modelstring
Ollama model to use (default: gemma3:4b) (default "gemma3:4b")-ostring
Output file to save matched URLs (optional)-ollama-hoststring
Ollama host (default: http://localhost:11434) (default "http://localhost:11434")-silent
Silent mode (only shows matched URLs)-timeoutint
HTTP timeout in seconds (default: 30) (default 30)-verbose
Enable verbose logging (shows info without errors)-workersint
Number of concurrent workers (default: 5) (default 5)
favlens helps map assets for a target by finding domains whose favicons are identical or visually similar to a known base favicon. This is useful for expanding visibility around a brand or organization.
Example reference pair:
https://bmwstocklocator.net/favicon.icohttps://bmw.com/favicon.icoThese may not be identical, but they can be visually similar.
Use a small Go program to stream all TLDs:
package main
import (
"fmt"
"github.com/picatz/tlds"
)
func main() {
for domain := range tlds.StreamAllDomains() {
fmt.Println(domain)
}
}Run it and save to a file:
go run tlds.go > tlds.txt
Concatenate a base label with each TLD to produce roots (example for bmw):
cat tlds.txt | xargs -P10 -I@ bash -c 'echo "bmw@"' > roots.txt
This yields candidates like bmw.com, bmw.net, bmw.org, etc.
Use dnsresolver to check ports and resolve candidates, then collect unique responsive hosts:
Repository: https://github.com/ethicalhackingplayground/dnsresolver
cat roots.txt | dnsresolver -p 80,443 -c 100 -r 100 --resolvers resolvers.txt | anew hosts.txt
-p 80,443checks HTTP/HTTPS-c 100sets concurrency-r 100sets resolution rateanewappends only new lines tohosts.txt
Feed collected hosts into favlens with your base favicon:
favlens -base https://www.bmw.com/favicon.ico -file hosts.txt -model gemma3:4b -o found.txt -verbose
-verboseshows progress without debug noise-o found.txtstores matched URLs for later analysis
Notes:
- Adjust concurrency and resolver settings to suit network policy and rate limits.
- Use the
-silentmode when you only need matched URLs.
Compare using defaults and save matches:
favlens -base https://example.com/favicon.ico -file urls.txt -o matched.txt
Increase concurrency and use a different model:
favlens -base https://example.com/favicon.ico -file urls.txt -workers 10 -model gemma3:4b
If you get a bounty using this tool, consider supporting by buying me a coffee!
