Skip to content

Commit

Permalink
Merge pull request #24 from shellrow/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
shellrow authored Jul 21, 2024
2 parents 24bedb0 + 0dc618c commit 9dbc52f
Show file tree
Hide file tree
Showing 56 changed files with 1,697 additions and 926 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nrev"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
authors = ["shellrow <shellrow@fortnium.com>"]
description = "Simple and Fast Network Revealer/Mapper."
Expand Down
16 changes: 7 additions & 9 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::{Mutex, OnceLock};
use clap::{crate_name, crate_version, crate_description};
use crate::sys;
use clap::{crate_description, crate_name, crate_version};
use std::sync::{Mutex, OnceLock};

// APP information
pub const CRATE_BIN_NAME: &str = "nrev";
Expand All @@ -13,11 +13,9 @@ pub static QUIET_MODE: OnceLock<Mutex<bool>> = OnceLock::new();
/// Check if quiet mode is enabled
pub fn is_quiet_mode() -> bool {
match QUIET_MODE.get() {
Some(mutex) => {
match mutex.try_lock() {
Ok(guard) => *guard,
Err(_) => false,
}
Some(mutex) => match mutex.try_lock() {
Ok(guard) => *guard,
Err(_) => false,
},
None => false,
}
Expand All @@ -29,7 +27,7 @@ pub fn set_quiet_mode(enabled: bool) -> Result<(), String> {
Ok(mut guard) => {
*guard = enabled;
Ok(())
},
}
Err(_) => Err("Failed to lock mutex".to_string()),
}
}
Expand Down Expand Up @@ -58,7 +56,7 @@ impl AppCommands {
"interfaces" => Some(AppCommands::Interfaces),
"interface" => Some(AppCommands::Interface),
"check" => Some(AppCommands::CheckDependencies),
_ => None
_ => None,
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ pub const PCAP_WAIT_TIME_MILLIS: u64 = 10;
pub const DEFAULT_PORTS_BIN: &[u8] = include_bytes!("../../resources/ndb-default-ports.bin");
pub const HTTP_PORTS_BIN: &[u8] = include_bytes!("../../resources/ndb-http-ports.bin");
pub const HTTPS_PORTS_BIN: &[u8] = include_bytes!("../../resources/ndb-https-ports.bin");
pub const OS_FAMILY_FINGERPRINT_BIN: &[u8] = include_bytes!("../../resources/ndb-os-family-fingerprint.bin");
pub const OS_FAMILY_FINGERPRINT_BIN: &[u8] =
include_bytes!("../../resources/ndb-os-family-fingerprint.bin");
pub const OS_TTL_BIN: &[u8] = include_bytes!("../../resources/ndb-os-ttl.bin");
pub const OS_FAMILY_BIN: &[u8] = include_bytes!("../../resources/ndb-os-family.bin");
pub const OUI_BIN: &[u8] = include_bytes!("../../resources/ndb-oui.bin");
Expand Down
21 changes: 15 additions & 6 deletions src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ pub fn get_vm_oui_map() -> HashMap<String, String> {

pub fn get_tcp_map() -> HashMap<u16, String> {
let mut tcp_map: HashMap<u16, String> = HashMap::new();
let ds_tcp_service: Vec<model::TcpService> = bincode::deserialize(config::TCP_SERVICE_BIN).unwrap_or(vec![]);
let ds_tcp_service: Vec<model::TcpService> =
bincode::deserialize(config::TCP_SERVICE_BIN).unwrap_or(vec![]);
for port in ds_tcp_service {
tcp_map.insert(port.port, port.service_name);
}
Expand All @@ -41,7 +42,8 @@ pub fn get_default_ports() -> Vec<u16> {
}

pub fn get_wellknown_ports() -> Vec<u16> {
let wellknown_ports: Vec<u16> = bincode::deserialize(config::WELLKNOWN_PORTS_BIN).unwrap_or(vec![]);
let wellknown_ports: Vec<u16> =
bincode::deserialize(config::WELLKNOWN_PORTS_BIN).unwrap_or(vec![]);
wellknown_ports
}

Expand Down Expand Up @@ -75,7 +77,8 @@ pub fn get_subdomain() -> Vec<String> {
}

pub fn get_os_family_fingerprints() -> Vec<model::OsFamilyFingerprint> {
let ds_os_fingerprints: Vec<model::OsFamilyFingerprint> = bincode::deserialize(config::OS_FAMILY_FINGERPRINT_BIN).unwrap_or(vec![]);
let ds_os_fingerprints: Vec<model::OsFamilyFingerprint> =
bincode::deserialize(config::OS_FAMILY_FINGERPRINT_BIN).unwrap_or(vec![]);
ds_os_fingerprints
}

Expand All @@ -85,7 +88,9 @@ pub fn get_os_family_list() -> Vec<String> {
}

pub fn is_vm_fingerprint(fingerprint: &model::OsFingerprint) -> bool {
if fingerprint.os_family == "Player".to_string() && fingerprint.device_type == "specialized".to_string() {
if fingerprint.os_family == "Player".to_string()
&& fingerprint.device_type == "specialized".to_string()
{
return true;
}
false
Expand Down Expand Up @@ -239,7 +244,11 @@ pub fn verify_os_family_fingerprint(fingerprint: &PacketFrame) -> model::OsFamil
};
}

pub fn get_os_family(fingerprint: &PacketFrame, os_family_list: &Vec<String>, os_family_fingerprints: &Vec<model::OsFamilyFingerprint>) -> model::OsFamilyFingerprint {
pub fn get_os_family(
fingerprint: &PacketFrame,
os_family_list: &Vec<String>,
os_family_fingerprints: &Vec<model::OsFamilyFingerprint>,
) -> model::OsFamilyFingerprint {
let in_vm: bool = if let Some(ether_header) = &fingerprint.ethernet_header {
in_vm_network(ether_header.clone())
} else {
Expand Down Expand Up @@ -383,7 +392,7 @@ pub fn get_fingerprint_map(fingerprints: &Vec<PacketFrame>) -> HashMap<IpAddr, S
let os_fingerprint = get_os_family(&f, &os_family_list, &os_family_fingerprints);
if let Some(ipv4_header) = &f.ipv4_header {
fingerprint_map.insert(IpAddr::V4(ipv4_header.source), os_fingerprint.os_family);
}else{
} else {
if let Some(ipv6_header) = &f.ipv6_header {
fingerprint_map.insert(IpAddr::V6(ipv6_header.source), os_fingerprint.os_family);
}
Expand Down
2 changes: 1 addition & 1 deletion src/db/tcp_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5844,4 +5844,4 @@ pub(crate) static PORT_SERVICE_MAP: Map<u16, &'static str> = phf_map! {
49000u16 => "matahari",
49001u16 => "nusrp",
49150u16 => "inspider",
};
};
1 change: 0 additions & 1 deletion src/dns/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use std::collections::HashMap;
use std::str::FromStr;
use std::thread;


#[cfg(not(target_os = "windows"))]
const DEFAULT_TIMEOUT: Duration = Duration::from_millis(200);
#[cfg(not(target_os = "windows"))]
Expand Down
2 changes: 1 addition & 1 deletion src/dns/result.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::scan::result::ScanStatus;

use super::domain::Domain;
use std::time::Duration;
use serde::{Deserialize, Serialize};
use std::time::Duration;

/// Result of domain scan
#[derive(Clone, Debug, Serialize, Deserialize)]
Expand Down
9 changes: 5 additions & 4 deletions src/dns/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ impl DomainScanner {
/// Results are stored in DomainScanner::scan_result
pub async fn run_scan(&mut self) {
if self.passive && cfg!(not(feature = "passive")) {
self.scan_result.scan_status = ScanStatus::Error(String::from("Passive scan not supported"));
self.scan_result.scan_status =
ScanStatus::Error(String::from("Passive scan not supported"));
return;
}
let start_time = Instant::now();
Expand Down Expand Up @@ -318,8 +319,8 @@ async fn scan_subdomain_passive(
if r.status().is_success() {
match r.text().await {
Ok(res_text) => {
let certs_json: serde_json::Value =
serde_json::from_str(res_text.as_str()).unwrap_or(serde_json::json!({}));
let certs_json: serde_json::Value = serde_json::from_str(res_text.as_str())
.unwrap_or(serde_json::json!({}));
if certs_json.is_array() {
let cert_array = certs_json.as_array().unwrap();
for cert in cert_array {
Expand Down Expand Up @@ -398,4 +399,4 @@ async fn scan_subdomain_passive(
result.push(domain.to_owned());
}
result
}
}
6 changes: 3 additions & 3 deletions src/fp/setting.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::net::IpAddr;
use serde::{Deserialize, Serialize};
use crate::protocol::Protocol;
use serde::{Deserialize, Serialize};
use std::net::IpAddr;

#[derive(Deserialize, Serialize, Clone, Copy, Debug, PartialEq, Eq)]
pub enum FingerprintType {
pub enum FingerprintType {
IcmpEcho,
IcmpTimestamp,
IcmpAddressMask,
Expand Down
4 changes: 2 additions & 2 deletions src/handler/check.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use clap::ArgMatches;
use crate::dep;
use clap::ArgMatches;

pub fn check_dependencies(_arg: &ArgMatches) {
match dep::check_dependencies() {
Ok(_) => {
println!("All dependencies are installed.");
std::process::exit(0);
},
}
Err(e) => {
println!("Error: {}", e);
std::process::exit(1);
Expand Down
79 changes: 50 additions & 29 deletions src/handler/dns.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::path::PathBuf;
use std::{thread, time::Duration};
use crate::db;
use crate::dns::domain::Domain;
use crate::dns::{result::DomainScanResult, scanner::DomainScanner};
use crate::util::tree::node_label;
use clap::ArgMatches;
use indicatif::{ProgressBar, ProgressDrawTarget};
use crate::dns::{result::DomainScanResult, scanner::DomainScanner};
use tokio::runtime::Runtime;
use std::path::PathBuf;
use std::{thread, time::Duration};
use termtree::Tree;
use crate::util::tree::node_label;
use tokio::runtime::Runtime;

use crate::output;

Expand Down Expand Up @@ -36,23 +36,21 @@ pub fn handle_subdomain_scan(args: &ArgMatches) {
Some(timeout) => Duration::from_millis(*timeout),
None => Duration::from_secs(30),
};

let word_list: Vec<String> = match host_args.get_one::<PathBuf>("wordlist") {
Some(file_path) => {
match std::fs::read_to_string(&file_path) {
Ok(contents) => {
let mut word_list: Vec<String> = Vec::new();
for word in contents.lines() {
let word = word.trim();
if word.is_empty() {
continue;
}
word_list.push(word.to_owned());
Some(file_path) => match std::fs::read_to_string(&file_path) {
Ok(contents) => {
let mut word_list: Vec<String> = Vec::new();
for word in contents.lines() {
let word = word.trim();
if word.is_empty() {
continue;
}
word_list
word_list.push(word.to_owned());
}
Err(_) => vec![],
word_list
}
Err(_) => vec![],
},
None => db::get_subdomain(),
};
Expand Down Expand Up @@ -94,22 +92,25 @@ pub fn handle_subdomain_scan(args: &ArgMatches) {
if args.get_flag("json") {
let json_result = serde_json::to_string_pretty(&result).unwrap();
println!("{}", json_result);
}else {
} else {
show_domainscan_result(&result, target_domain);
}
output::log_with_time(&format!("Scan completed in {:?}", result.scan_time), "INFO");
match args.get_one::<PathBuf>("save") {
Some(file_path) => {
match crate::fs::save_text(file_path, serde_json::to_string_pretty(&result).unwrap()) {
Ok(_) => {
output::log_with_time(&format!("Saved to {}", file_path.to_string_lossy()), "INFO");
},
output::log_with_time(
&format!("Saved to {}", file_path.to_string_lossy()),
"INFO",
);
}
Err(e) => {
output::log_with_time(&format!("Failed to save: {}", e), "ERROR");
},
}
}
},
None => {},
}
None => {}
}
}

Expand All @@ -120,10 +121,26 @@ fn print_option(setting: &DomainScanner) {
println!();
let mut tree = Tree::new(node_label("SubdomainScan Config", None, None));
let mut setting_tree = Tree::new(node_label("Settings", None, None));
setting_tree.push(node_label("Words", Some(&setting.word_list.len().to_string()), None));
setting_tree.push(node_label("Timeout", Some(&format!("{:?}", setting.timeout)), None));
setting_tree.push(node_label("Resolve timeout", Some(&format!("{:?}", setting.resolve_timeout)), None));
setting_tree.push(node_label("Concurrent limit", Some(&setting.concurrent_limit.to_string()), None));
setting_tree.push(node_label(
"Words",
Some(&setting.word_list.len().to_string()),
None,
));
setting_tree.push(node_label(
"Timeout",
Some(&format!("{:?}", setting.timeout)),
None,
));
setting_tree.push(node_label(
"Resolve timeout",
Some(&format!("{:?}", setting.resolve_timeout)),
None,
));
setting_tree.push(node_label(
"Concurrent limit",
Some(&setting.concurrent_limit.to_string()),
None,
));
tree.push(setting_tree);
let mut target_tree = Tree::new(node_label("Target", None, None));
target_tree.push(node_label("Domain Name", Some(&setting.base_domain), None));
Expand All @@ -135,7 +152,11 @@ fn show_domainscan_result(scan_result: &DomainScanResult, target_domain: Domain)
if !crate::app::is_quiet_mode() {
println!();
}
let mut tree = Tree::new(node_label(&format!("SubdomainScan Result - {}", target_domain.domain_name), None, None));
let mut tree = Tree::new(node_label(
&format!("SubdomainScan Result - {}", target_domain.domain_name),
None,
None,
));
let mut domain_tree = Tree::new(node_label(&target_domain.domain_name, None, None));
let mut ipv4_tree = Tree::new(node_label("IPv4 Addresses", None, None));
let mut ipv6_tree = Tree::new(node_label("IPv6 Addresses", None, None));
Expand Down
Loading

0 comments on commit 9dbc52f

Please sign in to comment.