|
1 | 1 | mod resolver; |
| 2 | + |
2 | 3 | // Import the necessary libraries |
3 | 4 | use clap::{App, Arg}; // Command-line argument parsing library |
4 | 5 | use futures::{stream::FuturesUnordered, StreamExt}; // Asynchronous programming library |
@@ -101,13 +102,27 @@ async fn main() -> std::io::Result<()> { |
101 | 102 | .display_order(5) |
102 | 103 | .help("checks if the host is a vhost and prints out the domains associated to the IP address"), |
103 | 104 | ) |
| 105 | + .arg( |
| 106 | + Arg::with_name("vhost-file") |
| 107 | + .long("vhost-file") |
| 108 | + .default_value("") |
| 109 | + .takes_value(true) |
| 110 | + .display_order(6) |
| 111 | + .help("the file containing a list of unresolved subdomains to check if they are virtual hosts"), |
| 112 | + ) |
| 113 | + .arg( |
| 114 | + Arg::with_name("check-localhost") |
| 115 | + .long("check-localhost") |
| 116 | + .display_order(7) |
| 117 | + .help("check if localhost is a vhost"), |
| 118 | + ) |
104 | 119 | .arg( |
105 | 120 | Arg::with_name("dir") |
106 | 121 | .short("d") |
107 | 122 | .long("dir") |
108 | 123 | .takes_value(true) |
109 | 124 | .default_value("vhosts") |
110 | | - .display_order(6) |
| 125 | + .display_order(7) |
111 | 126 | .help("the output directory to store all your virtual hosts that have been enumerated"), |
112 | 127 | ) |
113 | 128 | .get_matches(); |
@@ -156,6 +171,44 @@ async fn main() -> std::io::Result<()> { |
156 | 171 | }; |
157 | 172 | } |
158 | 173 |
|
| 174 | + let mut check_localhost = false; // Initialize a variable called `check_localhost` with the value `false` |
| 175 | + if vhost { |
| 176 | + // Check if the `vhost` variable is truthy |
| 177 | + |
| 178 | + check_localhost = matches.is_present("check-localhost"); // If `vhost` is truthy, assign the result of `matches.is_present("check-localhost")` to `check_localhost` |
| 179 | + } |
| 180 | + |
| 181 | + // Check if the command-line argument "vhost-file" has a value |
| 182 | + // If it has a value, assign it to the variable "vhost_files" |
| 183 | + // If it doesn't have a value, assign an empty string to "vhost_files" |
| 184 | + let vhost_path = match matches.value_of("vhost-file") { |
| 185 | + Some(v) => v, |
| 186 | + None => "", |
| 187 | + }; |
| 188 | + |
| 189 | + // Create an empty vector to store the vhost domains |
| 190 | + let mut vhosts_domains = vec![]; |
| 191 | + |
| 192 | + // Read the list of DNS resolvers from a file |
| 193 | + if !vhost_path.is_empty() { |
| 194 | + let vhost_file = match File::open(vhost_path) { |
| 195 | + Ok(f) => f, |
| 196 | + Err(err) => { |
| 197 | + // Print the error message and exit with code 1 |
| 198 | + eprintln!("{}", err); |
| 199 | + exit(1) |
| 200 | + } |
| 201 | + }; |
| 202 | + |
| 203 | + // Create a buffered reader to read the file line by line |
| 204 | + let vhost_reader = std::io::BufReader::new(vhost_file); |
| 205 | + |
| 206 | + // Iterate over each line in the file |
| 207 | + for dns_vhost in vhost_reader.lines() { |
| 208 | + vhosts_domains.push(dns_vhost.unwrap()); |
| 209 | + } |
| 210 | + } |
| 211 | + |
159 | 212 | // Parse the ports argument or use a default value |
160 | 213 | let ports = match matches.value_of("ports") { |
161 | 214 | Some(ports) => ports.to_string(), |
@@ -261,9 +314,19 @@ async fn main() -> std::io::Result<()> { |
261 | 314 | let jrx = job_rx.clone(); |
262 | 315 | let jtx = result_tx.clone(); |
263 | 316 | let out = outdir.clone(); |
| 317 | + let dns_domains = vhosts_domains.clone(); |
264 | 318 | workers.push(task::spawn(async move { |
265 | 319 | // run the detector |
266 | | - resolver::run_resolver(jtx, jrx, dns_resolver, vhost, out.as_str()).await |
| 320 | + resolver::run_resolver( |
| 321 | + jtx, |
| 322 | + jrx, |
| 323 | + dns_resolver, |
| 324 | + dns_domains, |
| 325 | + vhost, |
| 326 | + check_localhost, |
| 327 | + out, |
| 328 | + ) |
| 329 | + .await |
267 | 330 | })); |
268 | 331 | } |
269 | 332 |
|
|
0 commit comments