# Team 2: Topic 4 - Bug Bounty, Recon
## Goals (10 %)
- (4 %) Recon system secure deployment
- Based on CIA and workable
- Avoid hardcoding secrets, keys and sensitive data in source code
- Secure communications (e.g. TLS).
- Access Control, Authentication and Authorization.
- (4 %) Integrate 5 recon tools
- (2 %) Flexible/Extendable lifecycle and plugins
- Optional: (2 %) A Bug Bounty Rewards (money, thanks letter and swag ...)
- Solutions, Risk Assessment and Process are in Document
## Design

- Our platform starts with schedulers which are responsible for the following modules:
- domain searcher
- service searcher
- subdir searcher
- password cracker.
(Note that these modules are extendible, we can add modules if we desire)
- The scheduler sends the jobs to the job queue.
- The dispatcher takes the jobs from the job queue, and then spawns preemptible gcp VMs to run the job.
```json
{
"method": "ServiceSearcher",
"params": {
"company": "starbucks",
"domains": ["www.starbucks.com", "bb.starbucks.com",
"c.starbucks.com", "a.starbucks.com"],
"ports": "21-23,25,53,80,110-111,135,139,143,443,445,993,995,1723,3306,3389,5900,8080"
},
"sched_type": "service_searcher",
"timeout": 60
}
```
- The preemptible gcp VMs run the job they were assigned.
- Though they are "preemptible intances" that could die at any time, we could launch lots of instances to solve this issue.
- The synchronization with the database is done by writing data into the DB writer queue, and the database will read data from it and update the database.
```json
{
"method": "insert_asset_domain_port",
"params": {
"domain": "a.starbucks.com",
"ports": [80, 443]
}
}
```
- The scheduler then can use the information updated to schedule more jobs to achieve deeper scanning.
## Implementation
### Modules
The scheduler contains the following modules. We initially contain an example for each to provide basic functionality.
#### Domain Searcher
- Brute force subdomains of given base domains.
- e.g. starbucks.com, starbucks.cn
- Demo Tool: Sublist3r
- Hardship: Default behavior would output the results once after the entire scan. (Cost Long-Time)
- Solution: Modify output buffer to make it similar to stream output.
- Input: company, base domains
- Output: subdomains
#### Service Searcher
- Scan open ports of a given domain.
- Demo Tool: Python-nmap
- Hardship: Python-nmap default enables version detection (-sV), but it is **slow**.
- Solution: In our design, we only need to know if the port is open or not. So we disable version detection. (10 times faster)
- Input:
- company: string
- domains: list of string
- ports (optional): string
- Default is top 20 most used ports
`21-23,25,53,80,110-111,135,139,143,443,445,993,995,1723,3306,3389,5900,8080`
- Output:
- Open ports: list of int
#### Subdir Searcher
- Brute force directory paths of a given domain
- Demo Tool: Dirsearch
- Input: company, domains
- Output: subdirectories
- Future work: Combine with detecting service to prevent **false positive** results.
#### Password Cracker
- Brute force password of a given service
- Demo Tool: Hydra
- Supported service:
- rdp
- ssh
- telnet
- ftp
- vnc
- Input: domain, port
- Output: password
- Future work: Specified web application bruteforce. e.g. phpmyadmin, wordpress
#### Subdomain Takeover (Undergoing)
- Check if a given subdomain could be tookover
- Tool: Dig
- Implementation Logic
```python
def check_takeover(subdomain):
return (subdomain has CNAME) and (not subdomain has NS record)
```
- Input: subdomain
- Output: true or false
---
### Database
**Table**
- Asset Table (Only Query)
- Takeover Table (Only Query)
**api**
- insert_takeover(domain: String)
- return True
- query_takeover(compay: String)
- return List[String]
**API**
- [x] insert_company(comapny: str, description: str)
- Return True|False, message
- [x] insert_asset_domain(company: String, domains: List[String])
- Return: error_code, message
- [x] query_company_domain(company: String)
- Return: List[String]
- [x] check_asset_domain(company: String, domain: String)
- Return: True
**Table**
- Asset Table (Query port 0, Insert related port)
**API**
- [x] query_company_domain(company: String)
- Return: List[String]
- [x] insert_asset_domain_port(domain: String, port: List[Int])
- Return: True
**Table**
- Asset Table (Query port 80, 443)
- Asset_directory Table
- Directories Table
**API**
- [x] query_asset_domain(company: String)
- Return: List[String]
- [x] insert_domain_subdir(domain: String, port: int, subdirs: List[String])
- Return: True
- [x] query_subdirs(filter: String)
- Return List[String]
- [x] query_domain_subdirs(domain: String, filter: String)
- Return List[String]
- [x] check_domain_subdir(domain: String, subdir: String)
- Return True
**Table**
- Asset Table
- Succeed Password Table
- Asset_Password Table
**API**
- query_domain_ports(domain: String)
- return List[Int]
- insert_domain_port_succeed_account_password(domain: String, port: Int, account: String, Password: String)
- return True
- query_accounts()
- return List[Str]
- query_passwords()
- return List[Str]
**companies**
```sql
CREATE TABLE companies (
company_id integer PRIMARY KEY AUTOINCREMENT,
company text NOT NULL,
description text NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
unique (company)
);
```
**accounts**
```sql
CREATE TABLE accounts (
account_id integer PRIMARY KEY AUTOINCREMENT,
account text NOT NULL,
unique (account)
);
```
**secrets**
```sql
CREATE TABLE secrets (
secret_id integer PRIMARY KEY AUTOINCREMENT,
secret text NOT NULL,
unique (secret)
);
```
**directories**
```sql
CREATE TABLE directories (
directory_id integer PRIMARY KEY AUTOINCREMENT,
directory text NOT NULL,
unique (directory)
);
```
**assets**
```sql
CREATE TABLE assets (
asset_id integer PRIMARY KEY AUTOINCREMENT,
company_id integer NOT NULL,
domain_name text NOT NULL,
port integer default 0,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (company_id)
REFERENCES companies (company_id),
unique(company_id, domain_name, port)
);
```
**asset_account_secret**
```sql
CREATE TABLE asset_account_secret (
aas_id integer PRIMARY KEY AUTOINCREMENT,
asset_id integer NOT NULL references assets (asset_id),
account_id integer NOT NULL references accounts (account_id),
secret_id integer NOT NULL references secrets (secret_id),
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
unique (asset_id, account_id, secret_id)
);
```
**asset_directory**
```sql
CREATE TABLE asset_directory (
ad_id integer PRIMARY KEY AUTOINCREMENT,
asset_id integer NOT NULL,
directory_id integer NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (asset_id)
REFERENCES assets (asset_id),
FOREIGN KEY (directory_id)
REFERENCES directories (directory_id)
UNIQUE(asset_id, directory_id)
);
```
**asset_takeover**
```sql
CREATE TABLE asset_takeover (
tk_id integer PRIMARY KEY AUTOINCREMENT,
asset_id integer NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (asset_id)
REFERENCES assets (asset_id)
UNIQUE(asset_id)
);
```