![PyPI](https://img.shields.io/pypi/v/bbrf?style=flat-square)
![PyPI - Downloads](https://img.shields.io/pypi/dm/bbrf?style=flat-square)
[![Twitter Follow](https://img.shields.io/twitter/follow/honoki?style=flat-square)](https://twitter.com/honoki)
## Introduction
The Bug Bounty Reconnaissance Framework (BBRF) can be used to coordinate your reconnaissance workflows across multiple devices. For more background, read [the original blog post](https://honoki.net/2020/10/08/introducing-bbrf-yet-another-bug-bounty-reconnaissance-framework/).
If you are new to BBRF, you will need to deploy a [BBRF server](https://github.com/honoki/bbrf-server) before you can make use of the client.
### Get started
```bash
# install the client
pip install bbrf
# create the .bbrf folder
mkdir -p ~/.bbrf
# ensure you have the required configuration in ~/.bbrf/config.json
cat > ~/.bbrf/config.json << EOF
{
"username": "bbrf",
"password": "<your secure password>",
"couchdb": "https://<your-bbrf-server>/bbrf",
"slack_token": "<a slack token to receive notifications>",
"discord_webhook": "<your discord webhook if you want one>",
"ignore_ssl_errors": false
}
EOF
# other optional settings are {"debug":true, "slack_channel": "channel-name", "slack_webhook":"https://..."}
# create a new program
bbrf new test
# or continue with a program you have created before
bbrf use test
# define a scope for your program
bbrf inscope add '*.example.com' '*.sub.example.com' 'example.com'
bbrf outscope add 'blog.example.com' '*.dev.example.com'
# view the program in/out scope
bbrf scope in
bbrf scope out
# start a background listener to listen for changes and send alerts to Slack
# in production, you probably want this continuously running on a VPS somewhere
bbrf listen &
# add some domains manually
bbrf domain add www.example.com example.com some.dev.example.com www.example.com www.example.com thisisnotadomain.example
# note that bbrf automatically safeguards the data quality, e.g.
# it checks the program's in and out scope to see if entries
# should be processed or not, prevents duplicate entries in the database,
# and rejects all input that is not a valid domain
bbrf domains
# add a list of ips from a file by piping into bbrf
cat ips.txt | bbrf ip add -
# run a tool based on the program scope, store results in bbrf,
# and display a list of domains that have been added
bbrf scope in --wildcard --top | subfinder | bbrf domain add - --show-new
# retrieve a raw document from the bbrf server and format with jq
bbrf show www.example.com | jq
# update the outscope
bbrf outscope add www.example.com
# note that this does not automatically remove outscoped domains that
# were already in the database, so you will manually need to fix that!
bbrf domains | bbrf scope filter out | bbrf domain remove -
# discover all features of bbrf on the help page
bbrf -h
# Use dnsx to resolve unresolved domains across all your programs
# and store the results in bbrf, either by updating existing ips and domains,
# or by adding them if they are new
for p in $(bbrf programs); do
bbrf domains --view unresolved -p $p | \
dnsx -silent -a -resp | tr -d '[]' | tee \
>(awk '{print $1":"$2}' | bbrf domain update - -p $p -s dnsx) \
>(awk '{print $1":"$2}' | bbrf domain add - -p $p -s dnsx) \
>(awk '{print $2":"$1}' | bbrf ip add - -p $p -s dnsx) \
>(awk '{print $2":"$1}' | bbrf ip update - -p $p -s dnsx)
done
# view all resolved domains
bbrf domains --view resolved
```
### Python module
To use BBRF in your Python projects, use the interface as follows:
```python
from bbrf import BBRFClient as bbrf
# this will use the system's default ~/.bbrf/config.json file:
programs = bbrf('programs').run()
# to specify a custom configuration, provide a second argument:
conf = {
"username": "bbrf",
"password": "<your secure password>",
"couchdb": "https://<your-instance>/bbrf",
"slack_token": "<a slack token to receive notifications>",
"discord_webhook": "<your discord webhook>",
"ignore_ssl_errors": false
}
domains = bbrf('domains --view resolved', conf).run()
```
### Dashboard
If you like browsing through your recon data with a GUI, you can make use of the [BBRF dashboard](https://github.com/honoki/bbrf-dashboard) on https://bbrf.me. Just plug in your server URL, username and password, and the dashboard will pull your data and make it searchable. Note that all communication to the server happens via your browser, so your data remains safe!
[![asciicast](docs/bbrf-dashboard.gif)](https://bbrf.me/)
### Advanced
#### Domains
BBRF will accept and store domains in any of the following input formats:
```
<domain>
<domain>:<ip>
<domain>:<ip>,<ip>,...
```
Note that adding the DNS resolutions of a domain in this way does *not* automatically store the IP in the IPs table,
but that domains and ips are logically seperated in the client, which requires you to write your scripts so that they
handle this distinction appropriately.
```bash
bbrf domain add www.example.com:1.1.1.1
bbrf domain update www.example.com:2.2.2.2,3.3.3.3
bbrf show www.example.com | jq
```
#### IPs
Similarly, you can store hostnames of an IP address by appending one or more domains with a colon:
```
<ip>
<ip>:<domain>
<ip>:<domain>,<domain>,...
```
Again, BBRF will make sure the provided hostnames are valid domain names before storing them, but will not add them to your list of domains for the program, nor does it validate these domains against the defined program scope. Instead, these domains are stored in a `domains` property on the IP document:
```bash
bbrf ip add 1.1.1.1:www.example.com,sub.example.com
bbrf ip update 1.1.1.1:www.google.com,www.apple.com
bbrf show 1.1.1.1 | jq
```
#### URLs
BBRF will help you manage your URLs, and store their hostname, port, status code and content length for you:
```bash
bbrf url add 'https://www.example.com:8443/a' 'http://www.example.com/b' 'http://www.example.com/c 200 1234'
```
Two formats are accepted: `<url>` or `<url> <statuscode> <contentlength>` delimited by spaces.
The `<url>` can be absolute or relative. A relative URL will require the `-d <hostname>` flag to be specified or will be skipped. Whenever the `-d` flag is set, it will compare that with the hostname parsed from the URL, and skip the URL if they do not match.
Relative URLs and URLs that do not specify a scheme (`http://` or `https://`) will always be interpreted with scheme `http://`. If no port is found, ports 80 and 443 will be used as a default depending on the scheme.
The flag `--show-new` will print a list of new and updated URLs if they were added, or if their status code and/or content length were updated respectively:
```bash
cat urls.txt | bbrf url add - --show-new
[UPDATED] https://sub.example.com:8443/b
[NEW] http://www.example.com/a
[NEW] http://www.example.com/c
```
To view a list of stored URLs of your active program, simply use:
```bash
bbrf urls
```
Or, to return URLs belonging to a specific host:
```bash
bbrf urls -d www.example.com
```
To list URLs across all programs, run:
```bash
bbrf urls --all
```
To print full URLs with the saved query strings:
```bash
bbrf urls --all --with-query
```
#### Services
To store services (i.e. open ports) in BBRF, provide the input formatted as `ip:port` or `ip:port:service`, and manually specify other properties by means of the tagging system (see below for more info about tags), e.g.:
```bash
bbrf service add 127.0.0.1:8443 127.0.0.1:8888 -t hostname:localhost -t protocol:tcp
bbrf service add 127.0.0.1:80:http 127.0.0.1:21:ftp -t hostname:localhost -t protocol:tcp
bbrf service add 127.0.0.1:22:ssh 127.0.0.1:53:domain 127.0.0.1:80 -t scanned:$(date +%s)
```
Note that services