Create main.rs
This commit is contained in:
202
src/main.rs
Normal file
202
src/main.rs
Normal file
@@ -0,0 +1,202 @@
|
||||
use std::fs;
|
||||
use reqwest::{self, StatusCode};
|
||||
use clap::Parser;
|
||||
use std::thread;
|
||||
use dns_lookup::lookup_host;
|
||||
|
||||
|
||||
/// Subdomain Bruteforcer, and directory bruteforcer written in rust, and multi threaded!!!
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version, about, long_about = None)]
|
||||
struct Args{
|
||||
/// target to attack, can be a URL or a dns name, you can specify more than one by comma separating the targets
|
||||
#[arg(short, long)]
|
||||
target: String,
|
||||
|
||||
///Threads to use, there is not upper limit so if you lock up your comptuer that's on you
|
||||
#[arg(long)]
|
||||
threads: usize,
|
||||
|
||||
/// wordlist to use for subdomains
|
||||
#[arg(short, long, default_value_t = String::from("none"))]
|
||||
subwordlist: String,
|
||||
|
||||
///wordlist to use for directories
|
||||
#[arg(short, long, default_value_t = String::from("none"))]
|
||||
dirwordlist: String,
|
||||
}
|
||||
|
||||
|
||||
fn try_sub(domain: String){
|
||||
let ips = lookup_host(&domain);
|
||||
if ips.is_ok(){
|
||||
let mut ip_string = String::new();
|
||||
for ip in ips.unwrap(){
|
||||
ip_string = format!("{},{}",ip, ip_string);
|
||||
}
|
||||
println!("{} {}", domain, ip_string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn try_dir(url: String){
|
||||
let resp_stat = reqwest::blocking::get(&url);
|
||||
if resp_stat.is_ok(){
|
||||
let resp = resp_stat.unwrap().status();
|
||||
match resp{
|
||||
StatusCode::OK => println!("{} {}",resp, url),
|
||||
StatusCode::ACCEPTED => println!("{} {}", resp, url),
|
||||
StatusCode::CONTINUE => println!("{} {}", resp, url),
|
||||
StatusCode::CREATED => println!("{} {}", resp, url),
|
||||
StatusCode::FOUND => println!("{} {}", resp, url),
|
||||
StatusCode::IM_A_TEAPOT => println!("And what a beautiful teapot you are {}", url),
|
||||
StatusCode::MOVED_PERMANENTLY => println!("{} {}", resp, url),
|
||||
StatusCode::PERMANENT_REDIRECT => println!("{} {}", resp, url),
|
||||
StatusCode::TEMPORARY_REDIRECT => println!("{} {}", resp, url),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
print!("
|
||||
|
||||
|
||||
|
||||
|
||||
▄
|
||||
|
||||
╓╦▀
|
||||
|
||||
╓█▀
|
||||
|
||||
▀▀
|
||||
|
||||
|
||||
|
||||
╓▓
|
||||
|
||||
╓▄ ▄█▀
|
||||
|
||||
▄█▀▓▌ ▄█▀ ▄▀
|
||||
|
||||
▄█╙ █ ▀╙ ╓█▀
|
||||
|
||||
▄▀ █▄ ▄▄▄ ╓█▀
|
||||
|
||||
▐▌ ▐█ ▄▀└ ▐█ └
|
||||
|
||||
▐▌ ╓█▀ ▄█┘
|
||||
|
||||
╟▌ ▄█▀ ▄█▌
|
||||
|
||||
┌▄▄██╖ ▄█▀ ╓▄▀ └╙▀▀▀▀▓▄▄
|
||||
|
||||
▄▄▓▀╙ ▀██╙ ╓▓▀ ▄▀
|
||||
|
||||
╓▄▓▀└ ╙█▄█▀ ╓█▀
|
||||
|
||||
▄██▌ ▀▄ ▄█▀
|
||||
|
||||
▄█▀ ▀▌ ▐█▀▀▀▀▀▀▀╘
|
||||
|
||||
▄█▀ ▀▌ ╙█▄ ╓█
|
||||
|
||||
▄▀╙ ╙█┐ ▀▓╖ ▄█
|
||||
|
||||
╓▓▀ ▀▌ ▀█▄ ▄█
|
||||
|
||||
▄█▀ ▀▄ ╙▀▓▄ ▄▀
|
||||
|
||||
╓█▀ ▀█╖ ╙▀▓▄█▀
|
||||
|
||||
██ ╙▀▄╓ ▄▌
|
||||
|
||||
█╛▀█ ╙▀▓▄█▀
|
||||
|
||||
▓▌ █▄ ▄█
|
||||
|
||||
█░ ▀█┐ ▄█╘
|
||||
|
||||
█▌ ▀█╖ ▄█╙
|
||||
|
||||
█─ ▀█▄ ▄█╙
|
||||
|
||||
▄█▄ ▀█▄ ┌▄▀└
|
||||
|
||||
█▌ ▀█▄ ▀▀▄▄█▀
|
||||
|
||||
╙█▄▄▄▀▀▀▓▄▄▄▄▄▄▄▓▀▀
|
||||
|
||||
|
||||
");
|
||||
let mut dirs_to_try = Vec::new();
|
||||
let mut subs_to_try = Vec::new();
|
||||
let args = Args::parse();
|
||||
let mut targets = Vec::new();
|
||||
for target in args.target.split(",").collect::<Vec<&str>>(){
|
||||
targets.push(target.to_owned());
|
||||
}
|
||||
if args.dirwordlist != String::from("none"){
|
||||
let dirwordlist = fs::read_to_string(args.dirwordlist).expect("error reading directory wordlist");
|
||||
for dir in dirwordlist.split("\n").collect::<Vec<&str>>(){
|
||||
dirs_to_try.push(dir.trim_end().trim_start().to_owned());
|
||||
}
|
||||
}
|
||||
if args.subwordlist != String::from("none"){
|
||||
let subwordlist = fs::read_to_string(args.subwordlist).expect("error reading subdomain word list");
|
||||
for sub in subwordlist.split("\n").collect::<Vec<&str>>(){
|
||||
subs_to_try.push(sub.trim_end().trim_start().to_owned())
|
||||
}
|
||||
}
|
||||
let mut domains_to_try = Vec::new();
|
||||
let mut urls_to_try = Vec::new();
|
||||
println!("loading targets, and wordlists...");
|
||||
for target in targets{
|
||||
if target.contains("/"){
|
||||
for dir in &dirs_to_try{
|
||||
let url = format!("{}/{}", target, dir);
|
||||
urls_to_try.push(url.to_owned());
|
||||
}
|
||||
}
|
||||
else if target.contains(".") == true{
|
||||
for sub in &subs_to_try{
|
||||
let domain = format!("{}.{}", sub, target);
|
||||
domains_to_try.push(domain.to_owned());
|
||||
}
|
||||
}
|
||||
else{
|
||||
println!("{} is not a valid target, please supply either a domain or url", target);
|
||||
}
|
||||
}
|
||||
let mut threads = Vec::new();
|
||||
let urls_len = urls_to_try.len();
|
||||
let domains_len = domains_to_try.len();
|
||||
println!("DONE!, {} URLS to try, and {} subdomains to try", &urls_len, &domains_len);
|
||||
if urls_len > 0{
|
||||
let dir_chunk_size = urls_len / &args.threads;
|
||||
let url_vecs: Vec<Vec<String>> = urls_to_try.chunks(dir_chunk_size).map(|x| x.to_vec()).collect();
|
||||
for urlvec in url_vecs{
|
||||
for url in urlvec{
|
||||
threads.push(thread::spawn(move || {
|
||||
try_dir(url)
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
if domains_len > 0 {
|
||||
let domain_chunk_size = domains_len /&args.threads;
|
||||
let domain_vecs: Vec<Vec<String>> = domains_to_try.chunks(domain_chunk_size).map(|x| x.to_vec()).collect();
|
||||
for domainvec in domain_vecs{
|
||||
for domain in domainvec{
|
||||
threads.push(thread::spawn(move || {
|
||||
try_sub(domain);
|
||||
}))
|
||||
}
|
||||
}
|
||||
for thread in threads{
|
||||
let _ = thread.join();
|
||||
}
|
||||
}
|
||||
println!("done bruteforcing, happy hunting!");
|
||||
}
|
||||
Reference in New Issue
Block a user