Skip to content

Commit

Permalink
Add support for working with resolved subdomains only - remove ip opt…
Browse files Browse the repository at this point in the history
…ion.

The -i or --ip option was used to know what subdomains are resolvable but was not very usefull because the way that it show the data. The new -r / --resolved option allow the user to print or write to file only resolved domains without any aditional data.

Fixes: 20
  • Loading branch information
Edu4rdSHL committed Sep 26, 2019
1 parent 8e4909f commit 8765694
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 43 deletions.
8 changes: 4 additions & 4 deletions src/cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ args:
conflicts_with:
- file

- ip:
short: i
long: get-ip
help: Return the subdomain list with IP address if resolved.
- resolved:
short: r
long: resolved
help: Show/write only resolved subdomains.
takes_value: false

- file:
Expand Down
74 changes: 38 additions & 36 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ lazy_static! {

pub fn get_subdomains(
target: &str,
with_ip: &str,
only_resolved: &str,
with_output: &str,
file_name: &str,
unique_output_flag: &str,
Expand Down Expand Up @@ -272,7 +272,7 @@ pub fn get_subdomains(
manage_subdomains_data(
subdomains.iter().flatten().flat_map(|sub| sub).collect(),
&target,
&with_ip,
&only_resolved,
&with_output,
&file_name,
)?;
Expand All @@ -281,7 +281,7 @@ pub fn get_subdomains(
manage_subdomains_data(
subdomains.iter().flatten().flat_map(|sub| sub).collect(),
&target,
&with_ip,
&only_resolved,
&with_output,
&file_name,
)?;
Expand All @@ -298,7 +298,7 @@ pub fn get_subdomains(
fn manage_subdomains_data(
mut subdomains: HashSet<&String>,
target: &str,
with_ip: &str,
only_resolved: &str,
with_output: &str,
file_name: &str,
) -> Result<()> {
Expand All @@ -309,42 +309,53 @@ fn manage_subdomains_data(
&target
);
} else {
println!();
subdomains.retain(|sub| {
!sub.contains('*') && !sub.starts_with('.') && sub.ends_with(&base_target)
});
if with_ip == "y" && with_output == "y" {
let mut subdomains_resolved = 0;
if only_resolved == "y" && with_output == "y" {
for subdomain in &subdomains {
let ipadress = get_ip(&subdomain);
write_to_file(&subdomain, &ipadress, &file_name, &with_ip)?;
println!("{},{}", &subdomain, &ipadress);
if get_ip(subdomain) {
write_to_file(subdomain, file_name)?;
println!("{}", subdomain);
subdomains_resolved += 1
}
}
} else if with_ip == "y" && with_output != "y" {
show_subdomains_found(subdomains_resolved, target)
} else if only_resolved == "y" && with_output != "y" {
for subdomain in &subdomains {
let ipadress = get_ip(&subdomain);
println!("{},{}", &subdomain, &ipadress);
if get_ip(subdomain) {
println!("{}", subdomain);
subdomains_resolved += 1
}
}
} else if with_ip != "y" && with_output == "y" {
let ipadress = "";
show_subdomains_found(subdomains_resolved, target)
} else if only_resolved != "y" && with_output == "y" {
for subdomain in &subdomains {
write_to_file(&subdomain, &ipadress, &file_name, &with_ip)?;
println!("{}", &subdomain);
write_to_file(subdomain, file_name)?;
println!("{}", subdomain);
}
show_subdomains_found(subdomains.len(), target)
} else {
for subdomain in &subdomains {
println!("{}", &subdomain);
println!("{}", subdomain);
}
show_subdomains_found(subdomains.len(), target)
}
println!(
"\nA total of {} subdomains were found for ==> {} 👽",
&subdomains.len(),
&target
);
println!("\nGood luck Hax0r 💀!\n");
}

Ok(())
}

fn show_subdomains_found(subdomains_found: usize, target: &str) {
println!(
"\nA total of {} subdomains were found for ==> {} 👽",
subdomains_found, target
)
}

fn get_certspotter_subdomains(url_api_certspotter: &str) -> Option<HashSet<String>> {
println!("Searching in the CertSpotter API... 🔍");
match CLIENT.get(url_api_certspotter).send() {
Expand Down Expand Up @@ -518,7 +529,7 @@ fn check_json_errors(error: reqwest::Error, api: &str) {

pub fn read_from_file(
file: &str,
with_ip: &str,
only_resolved: &str,
with_output: &str,
file_name: &str,
unique_output_flag: &str,
Expand All @@ -535,7 +546,7 @@ pub fn read_from_file(
};
get_subdomains(
&domain,
&with_ip,
&only_resolved,
&with_output,
&file_name,
&unique_output_flag,
Expand All @@ -545,12 +556,7 @@ pub fn read_from_file(
Ok(())
}

fn write_to_file(data: &str, subdomain_ip: &str, file_name: &str, with_ip: &str) -> Result<()> {
let data = if with_ip == "y" {
[data, ",", subdomain_ip, "\n"].concat()
} else {
[data, "\n"].concat()
};
fn write_to_file(data: &str, file_name: &str) -> Result<()> {
let mut output_file = OpenOptions::new()
.append(true)
.create(true)
Expand All @@ -560,15 +566,11 @@ fn write_to_file(data: &str, subdomain_ip: &str, file_name: &str, with_ip: &str)
Ok(())
}

fn get_ip(domain: &str) -> String {
fn get_ip(domain: &str) -> bool {
let resolver = get_resolver();
match resolver.lookup_ip(&domain) {
Ok(ip_address) => ip_address
.iter()
.next()
.expect("An error has occurred getting the IP address.")
.to_string(),
Err(_) => String::from("No IP address found"),
Ok(_) => true,
Err(_) => false,
}
}

Expand Down
10 changes: 7 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ fn run() -> Result<()> {
} else {
empty_value.clone()
};
let with_ip = if matches.is_present("ip") { "y" } else { "" };
let only_resolved = if matches.is_present("resolved") {
"y"
} else {
""
};
let with_output = if matches.is_present("output") || matches.is_present("unique-output") {
"y"
} else {
Expand All @@ -37,7 +41,7 @@ fn run() -> Result<()> {
if matches.is_present("target") {
get_subdomains(
&target,
&with_ip,
&only_resolved,
&with_output,
&file_name,
&unique_output_flag,
Expand All @@ -46,7 +50,7 @@ fn run() -> Result<()> {
let file = matches.value_of("file").unwrap().to_string();
read_from_file(
&file,
&with_ip,
&only_resolved,
&with_output,
&file_name,
&unique_output_flag,
Expand Down

0 comments on commit 8765694

Please sign in to comment.