Skip to content

Dev #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 21, 2024
Merged

Dev #24

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
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
Loading