Skip to content

Commit

Permalink
v1.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
netevert committed Feb 10, 2019
1 parent 0def5ad commit 48234aa
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 21 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/extensions.json
data.db
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.2.1] - 2019-02-10

### Fixed

- Bug that crashed delator if the user had not created a local database
- Bug that crashed delator when A record lookups were requested on locally stored subdomains
- Minor documentation fixes and updates
- Miscellaneous fixes and improvements

## [1.2.0] - 2019-01-06

### Added
Expand Down
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,31 @@
[![Maintenance](https://img.shields.io/maintenance/yes/2019.svg?style=flat-square)]()
[![GitHub last commit](https://img.shields.io/github/last-commit/netevert/delator.svg?style=flat-square)](https://github.com/netevert/delator/commit/master)

DELATOR (*lat.* **informer**) is a tool to perform subdomain enumeration and initial reconnaissance through the abusing of certificate transparency logs. It expands on the original work done by [Sheila A. Berta](https://github.com/UnaPibaGeek) with her [CTFR](https://github.com/UnaPibaGeek/ctfr) tool and leverages the speed and power of [Go](https://golang.org/).
DELATOR (*lat.* **informer**) is a tool to perform subdomain enumeration and initial reconnaissance through the abusing of certificate transparency (CT) logs. It expands on the original work done by [Sheila A. Berta](https://github.com/UnaPibaGeek) with her [CTFR](https://github.com/UnaPibaGeek/ctfr) tool and leverages the speed and power of [Go](https://golang.org/).

![demo](https://github.com/netevert/delator/blob/master/docs/demo.gif)

Using DELATOR is as simple as running:

./delator -d facebook.com -s db
./delator -d facebook.com -s crt

To run DELATOR a domain (_-d_) and search source (_-s_) must always be specified.

DELATOR can also be instructed to resolve any subdomains found, giving a first indication of any live sites:

./delator -d facebook.com -s net -a
./delator -d facebook.com -s crt -a

DELATOR can also mine subdomains directly from CT logs for storage in a local database:

./delator -p

Once subdomains have been pulled from CT logs, queries can be made directly to the local database just by changing the search source from "_crt_" to "_db_":

./delator.exe -d starbucks.com -s db

Installation
============
There are two ways to install dnsmorph on your system:
There are two ways to install DELATOR on your system:

1. Downloading the pre-compiled binaries for your platform from the [latest release page](https://github.com/netevert/delator/releases) and extracting in a directory of your choosing.

Expand All @@ -45,4 +55,4 @@ This project adheres to [Semantic Versioning](https://semver.org/).
Like it?
=========

**DELATOR is under active development** so make sure you check back frequently for new releases. However if you like the tool please consider contributing.
**DELATOR is under active development** so make sure you check back frequently for new releases. If you like the tool please consider contributing.
67 changes: 52 additions & 15 deletions delator.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ var (
source = newSet.String("s", "", "search source")
resolve = newSet.Bool("a", false, "view A record")
store = newSet.Bool("p", false, "pull ct logs")
ver = newSet.Bool("v", false, "check version")
utilDescription = "delator -d <domain> -s <source> {db|net} [-acv]"
ver = newSet.Bool("v", false, "version check")
utilDescription = "delator -d <domain> -s <source> {db|crt} [-apv]"
myClient = &http.Client{Timeout: 10 * time.Second}
appVersion = "1.2.0"
appVersion = "1.2.1"
banner = `
8"""8 8""" 8 8"""8 ""8"" 8""88 8""8
8e 8 8eee 8e 8eee8 8e 8 8 8ee8e
Expand Down Expand Up @@ -220,8 +220,7 @@ func dumpData(CommonName string) {
database.Close()
}

// Prints out a short bit of info about |cert|, found at |index| in the
// specified log
// dumps cert information into local database
func logCertInfo(entry *ct.RawLogEntry) {
logCount++
fmt.Printf("\rProgress: %d/%d", logCount, logSize)
Expand All @@ -236,8 +235,7 @@ func logCertInfo(entry *ct.RawLogEntry) {
}
}

// Prints out a short bit of info about |precert|, found at |index| in the
// specified log
// dumps precert information into local database
func logPrecertInfo(entry *ct.RawLogEntry) {
logCount++
fmt.Printf("\rProgress: %d/%d", logCount, logSize)
Expand All @@ -252,6 +250,7 @@ func logPrecertInfo(entry *ct.RawLogEntry) {
}
}

// helper function to create regexes
func createRegexes(regexValue string) (*regexp.Regexp, *regexp.Regexp) {
// Make a regex matcher
var certRegex *regexp.Regexp
Expand Down Expand Up @@ -454,6 +453,16 @@ func grabCTLog(inputLog string) {
scanner.Scan(ctx, logCertInfo, logPrecertInfo)
}

// checks if local sqlite database exists
func databaseCheck() {
if _, err := os.Stat("data.db"); err == nil {
// do nothing, carry on
} else if os.IsNotExist(err) {
r.Printf("database missing, create one\n")
storeKnownLogs()
}
}

// reads subdomains from database
func readDatabase() {
var id int
Expand All @@ -479,10 +488,14 @@ func readDatabase() {
}

// reads subdomains from database
func queryDatabase(query string) {
func queryDatabase(query string) []string {
databaseCheck()
var subdomains []string
var id int
var subdomain string
database, _ := sql.Open("sqlite3", "./data.db")
defer database.Close()

rows, err := database.Query(fmt.Sprintf("SELECT id, subdomain FROM subdomains WHERE subdomain LIKE '%%%s%%'", query))
if err != nil {
fmt.Println(err)
Expand All @@ -493,13 +506,23 @@ func queryDatabase(query string) {
if err != nil {
fmt.Println(err)
}
y.Printf(subdomain + "\n")
subdomains = append(subdomains, subdomain)
}
err = rows.Err()
if err != nil {
fmt.Println(err)
}
database.Close()
return subdomains
}

// converts a list of subdomains into data struct objects
func NormaliseDBData(inputData []string) (outputData []data) {
for i := range(inputData) {
var tmpData data
tmpData.NameValue = inputData[i]
outputData = append(outputData, tmpData)
}
return outputData
}

// sets up command-line arguments and default responses
Expand All @@ -517,11 +540,13 @@ func setup() {
// workaround to suppress glog errors, as per https://github.com/kubernetes/kubernetes/issues/17162#issuecomment-225596212
flag.CommandLine.Parse([]string{})

// check if user wants to download CT logs locally
if *store {
storeKnownLogs()
os.Exit(1)
}

// check if user wants to run version check
if *ver {
y.Printf("DELATOR")
fmt.Printf(" v.%s\n", appVersion)
Expand All @@ -532,15 +557,17 @@ func setup() {
os.Exit(1)
}

// check if user has supplied domain
if *domain == "" {
r.Printf("\nplease supply a domain\n\n")
fmt.Println(utilDescription)
newSet.PrintDefaults()
os.Exit(1)
}

// check if user has supplied source
if *source == "" {
r.Printf("\nplease supply a source {db|all}\n\n")
r.Printf("\nplease supply a source {db|crt}\n\n")
fmt.Println(utilDescription)
newSet.PrintDefaults()
os.Exit(1)
Expand All @@ -550,7 +577,9 @@ func setup() {
// main program entry point
func main() {
setup()
if *source == "net" {

// mine data from crt.sh
if *source == "crt" {
sanitizedDomain := sanitizedInput(*domain)
subdomains := fetchData(fmt.Sprintf("https://crt.sh/?q=%s&output=json", sanitizedDomain))
if *resolve {
Expand All @@ -560,13 +589,21 @@ func main() {
}
os.Exit(1)
}

// mine data from local database
if *source == "db" {
sanitizedDomain := sanitizedInput(*domain)
queryDatabase(sanitizedDomain)
if *resolve {
printResults(queryDatabase(sanitizedDomain))
} else {
printData(NormaliseDBData(queryDatabase(sanitizedDomain)))
}
os.Exit(1)
}
if *source != "net" || *source != "db" {
r.Printf("\ninvalid source [db|all]\n\n")

// Check if user has supplied the correct source
if *source != "crt" || *source != "db" {
r.Printf("\ninvalid source [db|crt]\n\n")
fmt.Println(utilDescription)
newSet.PrintDefaults()
os.Exit(1)
Expand Down

0 comments on commit 48234aa

Please sign in to comment.