diff --git a/.Rbuildignore b/.Rbuildignore index 451a4dd..46b2e57 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -7,6 +7,7 @@ ^NOTES\.*html$ ^\.codecov\.yml$ ^README_files$ +^README_cache$ ^doc$ ^tmp$ ^notes$ diff --git a/R/zdns-bulk-query.R b/R/zdns-bulk-query.R index ccf9fcb..2b3fbe9 100644 --- a/R/zdns-bulk-query.R +++ b/R/zdns-bulk-query.R @@ -32,12 +32,52 @@ #' @note if you specified `TRUE` for `log` then _you_ are responsible for #' removing the auto-generated log file. #' @export +#' @examples \dontrun{ +#' # enumerate top prefixes for a domain +#' +#' c( +#' "www", "mail", "mx", "blog", "ns1", "ns2", "dev", "server", "email", +#' "cloud", "api", "support", "smtp", "app", "webmail", "test", "box", +#' "m", "admin", "forum", "news", "web", "mail2", "ns", "demo", "my", +#' "portal", "shop", "host", "cdn", "git", "vps", "mx1", "mail1", +#' "static", "help", "ns3", "beta", "chat", "secure", "staging", "vpn", +#' "apps", "server1", "ftp", "crm", "new", "wiki", "home", "info" +#' ) -> top_common_prefixes +#' +#' tf <- tempfile(fileext = ".json") +#' +#' zdns_query( +#' sprintf("%s.rstudio.com", top_common_prefixes), +#' query_type = "A", +#' num_nameservers = (length(top_common_prefixes) * 2), +#' output_file = tf +#' ) +#' +#' res <- jsonlite::stream_in(file(tf)) +#' +#' found <- which(lengths(res$data$answers) > 0) +#' +#' do.call( +#' rbind.data.frame, +#' lapply(found, function(idx) { +#' res$data$answers[[idx]]$query_name <- res$name[idx] +#' res$data$answers[[idx]] +#' }) +#' ) -> xdf +#' +#' xdf <- xdf[,c("query_name", "name", "class", "ttl", "type", "answer")] +#' +#' knitr::kable(xdf) +#' } zdns_query <- function(entities, input_file = NULL, query_type = "A", output_file, num_nameservers = 3000L, num_retries = 3, log = TRUE, verbose = 3) { - # setup entities to lookup + # make sure the output file dir exists + output_file <- path.expand(output_file) + stopifnot(dir.exists(dirname(output_file))) + # setup entities to lookup if (!is.null(input_file)) { input_file <- path.expand(input_file) if (!file.exists(input_file)) stop("input file not found", call.=FALSE) diff --git a/R/zdns-exec.R b/R/zdns-exec.R index cbcd511..4c0737c 100644 --- a/R/zdns-exec.R +++ b/R/zdns-exec.R @@ -8,6 +8,11 @@ #' @export zdns_exec <- function(args=c(), stdout="", stdin="") { + if (!dir.exists(path.expand("~/.zdnsr"))) { + message("Bootstrapping public nameservers list...") + refresh_publc_nameservers_list() + } + zdns_bin <- Sys.which("zdns") res <- system2(zdns_bin, args=args, stdout=stdout, stdin=stdin) diff --git a/R/zzz.R b/R/zzz.R index e0575b0..9f9cde8 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,23 +1,20 @@ .onLoad <- function(libname, pkgname) { - if (!dir.exists(path.expand("~/.zdnsr"))) { - message("Bootstrapping public nameservers list...") - refresh_publc_nameservers_list() - } - res <- Sys.which("go") + if (res == "") { packageStartupMessage( - "Go (golang) not found. Please install Go (https://golang.org/dl/) for ", - "your platform and try reloading the package again." + "Go (golang) binary not found. Please install Go (https://golang.org/dl/) for ", + "your platform (and ensure $GOPATH/bin is on the system PATH) and try reloading the package again." ) } else { res <- Sys.which("zdns") if (res == "") { packageStartupMessage( - "zdns not found. Please go to https://github.com/zmap/zdns to find ", - "installation instructions or try running install_zdns()." + "zdns binary not found. Please go to https://github.com/zmap/zdns to find ", + "installation instructions or try running install_zdns() and/or ensure that .", + "$GOPATH/bin is on the system PATH reachable by R." ) } diff --git a/README.Rmd b/README.Rmd index 0722ad3..b5c2bcf 100644 --- a/README.Rmd +++ b/README.Rmd @@ -43,3 +43,41 @@ packageVersion("zdnsr") ``` +### Example (top prefix enumeration) + +```{r cache=TRUE} +c( + "www", "mail", "mx", "blog", "ns1", "ns2", "dev", "server", "email", + "cloud", "api", "support", "smtp", "app", "webmail", "test", "box", + "m", "admin", "forum", "news", "web", "mail2", "ns", "demo", "my", + "portal", "shop", "host", "cdn", "git", "vps", "mx1", "mail1", + "static", "help", "ns3", "beta", "chat", "secure", "staging", "vpn", + "apps", "server1", "ftp", "crm", "new", "wiki", "home", "info" +) -> top_common_prefixes # via Rapid7 FDNS analysis + +tf <- tempfile(fileext = ".json") + +zdns_query( + sprintf("%s.rstudio.com", top_common_prefixes), + query_type = "A", + num_nameservers = (length(top_common_prefixes) * 2), + output_file = tf +) + +res <- jsonlite::stream_in(file(tf)) +unlink(tf) + +found <- which(lengths(res$data$answers) > 0) + +do.call( + rbind.data.frame, + lapply(found, function(idx) { + res$data$answers[[idx]]$query_name <- res$name[idx] + res$data$answers[[idx]] + }) +) -> xdf + +xdf <- xdf[,c("query_name", "name", "class", "ttl", "type", "answer")] + +knitr::kable(xdf) +``` diff --git a/README.md b/README.md index a09e6a2..ddd3ba6 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,160 @@ packageVersion("zdnsr") ``` ## [1] '0.1.0' + +### Example (top prefix enumeration) + +``` r +c( + "www", "mail", "mx", "blog", "ns1", "ns2", "dev", "server", "email", + "cloud", "api", "support", "smtp", "app", "webmail", "test", "box", + "m", "admin", "forum", "news", "web", "mail2", "ns", "demo", "my", + "portal", "shop", "host", "cdn", "git", "vps", "mx1", "mail1", + "static", "help", "ns3", "beta", "chat", "secure", "staging", "vpn", + "apps", "server1", "ftp", "crm", "new", "wiki", "home", "info" +) -> top_common_prefixes # via Rapid7 FDNS analysis + +tf <- tempfile(fileext = ".json") + +zdns_query( + sprintf("%s.rstudio.com", top_common_prefixes), + query_type = "A", + num_nameservers = (length(top_common_prefixes) * 2), + output_file = tf +) +``` + + ## zmap error log will be stored in /var/folders/1w/2d82v7ts3gs98tc6v772h8s40000gp/T//RtmpQLNb6f/zmap-error6f90237c7564.json + +``` r +res <- jsonlite::stream_in(file(tf)) +``` + + ## opening file input connection. + + ## + Found 50 records... + Imported 50 records. Simplifying... + + ## closing file input connection. + +``` r +unlink(tf) + +found <- which(lengths(res$data$answers) > 0) + +do.call( + rbind.data.frame, + lapply(found, function(idx) { + res$data$answers[[idx]]$query_name <- res$name[idx] + res$data$answers[[idx]] + }) +) -> xdf + +xdf <- xdf[,c("query_name", "name", "class", "ttl", "type", "answer")] + +knitr::kable(xdf) +``` + +| query\_name | name | class | ttl | type | answer | +| :------------------ | :------------------------- | :---- | ---: | :---- | :-------------------------- | +| wiki.rstudio.com | wiki.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| wiki.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| cloud.rstudio.com | cloud.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| cloud.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| support.rstudio.com | support.rstudio.com | IN | 2978 | CNAME | rstudioide.ssl.zendesk.com. | +| support.rstudio.com | rstudioide.ssl.zendesk.com | IN | 278 | CNAME | rstudioide.zendesk.com. | +| support.rstudio.com | rstudioide.zendesk.com | IN | 563 | A | 35.174.158.178 | +| support.rstudio.com | rstudioide.zendesk.com | IN | 563 | A | 54.208.38.43 | +| support.rstudio.com | rstudioide.zendesk.com | IN | 563 | A | 35.174.160.246 | +| test.rstudio.com | test.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| test.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| vpn.rstudio.com | vpn.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| vpn.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| ns.rstudio.com | ns.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| ns.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| admin.rstudio.com | admin.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| admin.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| mail2.rstudio.com | mail2.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| mail2.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| static.rstudio.com | static.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| static.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| mx1.rstudio.com | mx1.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| mx1.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| ns3.rstudio.com | ns3.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| ns3.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| dev.rstudio.com | dev.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| dev.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| ns1.rstudio.com | ns1.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| ns1.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| www.rstudio.com | www.rstudio.com | IN | 3600 | CNAME | rstudio.wpengine.com. | +| www.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| staging.rstudio.com | staging.rstudio.com | IN | 299 | CNAME | www.rstudio.com. | +| staging.rstudio.com | www.rstudio.com | IN | 3599 | CNAME | rstudio.wpengine.com. | +| staging.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| news.rstudio.com | news.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| news.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| ns2.rstudio.com | ns2.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| ns2.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| email.rstudio.com | email.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| email.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| server.rstudio.com | server.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| server.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| shop.rstudio.com | shop.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| shop.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| crm.rstudio.com | crm.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| crm.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| host.rstudio.com | host.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| host.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| info.rstudio.com | info.rstudio.com | IN | 3600 | CNAME | mkto-ab020217.com. | +| info.rstudio.com | mkto-ab020217.com | IN | 300 | A | 199.15.213.48 | +| web.rstudio.com | web.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| web.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| portal.rstudio.com | portal.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| portal.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| mx.rstudio.com | mx.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| mx.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| mail1.rstudio.com | mail1.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| mail1.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| webmail.rstudio.com | webmail.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| webmail.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| api.rstudio.com | api.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| api.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| help.rstudio.com | help.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| help.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| secure.rstudio.com | secure.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| secure.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| new.rstudio.com | new.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| new.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| my.rstudio.com | my.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| my.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| vps.rstudio.com | vps.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| vps.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| smtp.rstudio.com | smtp.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| smtp.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| demo.rstudio.com | demo.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| demo.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| git.rstudio.com | git.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| git.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| cdn.rstudio.com | cdn.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| cdn.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| m.rstudio.com | m.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| m.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| mail.rstudio.com | mail.rstudio.com | IN | 3600 | CNAME | ghs.googlehosted.com. | +| mail.rstudio.com | ghs.googlehosted.com | IN | 69 | A | 172.217.6.243 | +| forum.rstudio.com | forum.rstudio.com | IN | 59 | CNAME | rstudio.wpengine.com. | +| forum.rstudio.com | rstudio.wpengine.com | IN | 119 | A | 104.196.200.5 | +| box.rstudio.com | box.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| box.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| home.rstudio.com | home.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| home.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| chat.rstudio.com | chat.rstudio.com | IN | 30 | CNAME | rstudio.wpengine.com. | +| chat.rstudio.com | rstudio.wpengine.com | IN | 30 | A | 104.196.200.5 | +| beta.rstudio.com | beta.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| beta.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| ftp.rstudio.com | ftp.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| ftp.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | +| blog.rstudio.com | blog.rstudio.com | IN | 300 | CNAME | rstudio-blog.netlify.com. | +| blog.rstudio.com | rstudio-blog.netlify.com | IN | 20 | A | 35.198.30.40 | +| server1.rstudio.com | server1.rstudio.com | IN | 60 | CNAME | rstudio.wpengine.com. | +| server1.rstudio.com | rstudio.wpengine.com | IN | 120 | A | 104.196.200.5 | diff --git a/README_cache/gfm/__packages b/README_cache/gfm/__packages new file mode 100644 index 0000000..718830f --- /dev/null +++ b/README_cache/gfm/__packages @@ -0,0 +1,8 @@ +base +methods +datasets +utils +grDevices +graphics +stats +zdnsr diff --git a/README_cache/gfm/unnamed-chunk-4_5b1895e28ea97b21405ef83abc3a3d11.RData b/README_cache/gfm/unnamed-chunk-4_5b1895e28ea97b21405ef83abc3a3d11.RData new file mode 100644 index 0000000..8f6c208 Binary files /dev/null and b/README_cache/gfm/unnamed-chunk-4_5b1895e28ea97b21405ef83abc3a3d11.RData differ diff --git a/README_cache/gfm/unnamed-chunk-4_5b1895e28ea97b21405ef83abc3a3d11.rdb b/README_cache/gfm/unnamed-chunk-4_5b1895e28ea97b21405ef83abc3a3d11.rdb new file mode 100644 index 0000000..d7980a3 Binary files /dev/null and b/README_cache/gfm/unnamed-chunk-4_5b1895e28ea97b21405ef83abc3a3d11.rdb differ diff --git a/README_cache/gfm/unnamed-chunk-4_5b1895e28ea97b21405ef83abc3a3d11.rdx b/README_cache/gfm/unnamed-chunk-4_5b1895e28ea97b21405ef83abc3a3d11.rdx new file mode 100644 index 0000000..3ea461f Binary files /dev/null and b/README_cache/gfm/unnamed-chunk-4_5b1895e28ea97b21405ef83abc3a3d11.rdx differ