Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ end
# gem 'ronin-support', '~> 1.1', github: 'ronin-rb/ronin-support',
# branch: 'main'

# gem 'ronin-core', '~> 0.2', github: 'ronin-rb/ronin-core',
# branch: 'main'
gem 'ronin-core', '~> 0.3', github: 'ronin-rb/ronin-core',
branch: '0.3.0'

# gem 'ronin-repos', '~> 0.1', github: 'ronin-rb/ronin-repos',
# branch: 'main'
Expand Down
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Commands:
irb
new
run
test
run-worker, test
worker
workers
```
Expand Down Expand Up @@ -219,21 +219,19 @@ Generate a boilerplate recon worker file, with some custom information:

```shell
$ ronin-recon new example_worker.rb \
--name Example \
--authors Postmodern \
--author Postmodern \
--description "This is an example."
```

Generate a ronin repository of your own payloads (or exploits):
Generate a ronin repository of your own recon workers:

```shell
$ ronin-repos new my-repo
$ cd my-repo/
$ mkdir recon
$ ronin-recon new recon/my_recon.rb \
--name MyRecon \
--authors You \
--description "This is my payload."
--author You \
--description "This is my recon worker."
$ vim recon/my_recon.rb
$ git add recon/my_recon.rb
$ git commit
Expand Down Expand Up @@ -313,7 +311,7 @@ end
* [async-http] ~> 0.60
* [wordlist] ~> 1.0, >= 1.0.3
* [ronin-support] ~> 1.1
* [ronin-core] ~> 0.2
* [ronin-core] ~> 0.3
* [ronin-db] ~> 0.2
* [ronin-repos] ~> 0.1
* [ronin-nmap] ~> 0.1
Expand Down
2 changes: 1 addition & 1 deletion data/templates/worker.rb.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env -S ronin-recon test -f
#!/usr/bin/env -S ronin-recon run-worker -f

require 'ronin/recon/<%= @worker_type[:file] -%>'

Expand Down
4 changes: 2 additions & 2 deletions gemspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ generated_files:
- man/ronin-recon-new.1
- man/ronin-recon-workers.1
- man/ronin-recon-worker.1
- man/ronin-recon-test.1
- man/ronin-recon-run-worker.1
- man/ronin-recon-run.1
- data/wordlists/subdomains-1000.txt.gz
- data/wordlists/raft-small-directories.txt.gz
Expand All @@ -46,7 +46,7 @@ dependencies:
wordlist: ~> 1.0, >= 1.0.3
# Ronin dependencies:
ronin-support: ~> 1.1
ronin-core: ~> 0.2
ronin-core: ~> 0.3
ronin-db: ~> 0.2
ronin-repos: ~> 0.1
ronin-nmap: ~> 0.1
Expand Down
129 changes: 129 additions & 0 deletions lib/ronin/recon/builtin/api/built_with.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# frozen_string_literal: true
#
# ronin-recon - A micro-framework and tool for performing reconnaissance.
#
# Copyright (c) 2023-2024 Hal Brodigan ([email protected])
#
# ronin-recon is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ronin-recon is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ronin-recon. If not, see <https://www.gnu.org/licenses/>.
#

require_relative '../../worker'

require 'async/http/internet/instance'
require 'set'

module Ronin
module Recon
module API
#
# A recon worker that queries https://api.builtwith.com and return
# informations for given domain
#
# ## Environment Variables
#
# * `BUILT_WITH_API_KEY` - Specifies the API key used for authorization.
#
class BuiltWith < Worker

register 'api/built_with'

summary "Queries the domain informations from https://api.builtwith.com"
description <<~DESC
Queriest the domain informations from https://api.builtwith.com.

The BuiltWith API key can be specified via the api/built_with.api_key
param or the BUILT_WITH_API_KEY environment variables.
DESC

accepts Domain
outputs Domain, EmailAddress
intensity :passive
concurrency 1

param :api_key, String, required: true,
default: ENV['BUILT_WITH_API_KEY'],
desc: 'The API key for BuiltWith'

# The HTTP client for `https://api.builtwith.com`
#
# @return [Async::HTTP::Client]
#
# @api private
attr_reader :client

#
# Initializes the `api/built_with` worker.
#
# @param [Hash{Symbol => Object}] kwargs
# Additional keyword arguments.
#
# @api private
#
def initialize(**kwargs)
super(**kwargs)

@client = Async::HTTP::Client.new(
Async::HTTP::Endpoint.for('https', 'api.builtwith.com')
)
end

#
# Returns all informations queried for given domain
#
# @param [Values::Domain] domain
# The domain value to gather informations for.
#
# @yield [Value] value
# The found value will be yielded
#
# @yieldparam [Values::Domain, Values::EmailAddress]
# The found domains or email addresses
#
def process(domain)
path = "/v21/api.json?KEY=#{params[:api_key]}&LOOKUP=#{domain}"
response = client.get(path)
body = begin
JSON.parse(response.read, symbolize_names: true)
ensure
response.close
end

domains = Set.new
email_addresses = Set.new

if (results = body[:Results])
results.each do |result|
if (paths = result.dig(:Result, :Paths))
paths.each do |result_path|
if (sub_domain = result_path[:SubDomain])
new_domain = "#{sub_domain}.#{domain}"

yield Domain.new(new_domain) if domains.add?(new_domain)
end
end
end

if (emails = result.dig(:Meta, :Emails))
emails.each do |email|
yield EmailAddress.new(email) if email_addresses.add?(email)
end
end
end
end
end

end
end
end
end
115 changes: 115 additions & 0 deletions lib/ronin/recon/builtin/api/hunter_io.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# frozen_string_literal: true
#
# ronin-recon - A micro-framework and tool for performing reconnaissance.
#
# Copyright (c) 2023-2024 Hal Brodigan ([email protected])
#
# ronin-recon is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ronin-recon is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ronin-recon. If not, see <https://www.gnu.org/licenses/>.
#

require_relative '../../worker'

require 'async/http/internet'

module Ronin
module Recon
module API
#
# A recon worker that queries https://api.hunter.io/domain-search
# and returns corresponding email addresses.
#
# ## Environment Variables
#
# * `HUNTER_IO_API_KEY` - Specifies the API key used for authorization.
#
class HunterIO < Worker

register 'api/hunter_io'

summary "Queries the Domains https://api.hunter.io/domain-search"
description <<~DESC
Queries the Domains https://api.hunter.io/domain-search and returns
corresponding email addresses.

The hunter.io API key can be specified via the api/hunter_io.api_key
param or the HUNTER_IO_API_KEY env variables.
DESC

accepts Domain
outputs EmailAddress
intensity :passive
concurrency 1

param :api_key, String, required: true,
default: ENV['HUNTER_IO_API_KEY'],
desc: 'The API key for hunter.io'

# The HTTP client for `https://api.hunter.io`.
#
# @return [Async::HTTP::Client]
#
# @api private
attr_reader :client

#
# Initializes the `api/hunter` worker.
#
# @param [Hash{Symbol => Object}] kwargs
# Additional keyword arguments.
#
# @api private
#
def initialize(**kwargs)
super(**kwargs)

@client = Async::HTTP::Client.new(
Async::HTTP::Endpoint.for('https', 'api.hunter.io')
)
end

#
# Returns email addresses corresponding to domain."
#
# @param [Values::Domain] domain
# The domain value to gather email addresses for.
#
# @yield [email]
# For each email address found through the API, a EmailAddress
# value will be yielded.
#
# @yieldparam [Values::EmailAddress] email_address
# The emial addresses found.
#
def process(domain)
path = "/v2/domain-search?domain=#{domain}&api_key=#{params[:api_key]}"
response = @client.get(path)
body = begin
JSON.parse(response.read, symbolize_names: true)
ensure
response.close
end

if (emails = body.dig(:data, :emails))
emails.each do |email|
if (email_addr = email[:value])
yield EmailAddress.new(email_addr)
end
end
end
end

end
end
end
end
Loading