diff --git a/src/main.rs b/src/main.rs index b52204e..938d826 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ +mod ports; + use std::{ cmp::min, - env, - ffi::OsString, - net::IpAddr, - path::PathBuf, + mem, + net::{IpAddr, Ipv4Addr}, str::FromStr, time::{Duration, Instant}, }; @@ -12,11 +12,15 @@ use clap::{Parser, Subcommand}; use parse_ip_range::parse_ip_targets; use rand::{rng, seq::SliceRandom}; use untitled::{ - database::ResultDatabase, online_scan, parse_ip_range, port_scan::tcp_scan, query, + database::ResultDatabase, + online_scan, + parse_ip_range::{self, generate_random_ipv4_addresses}, + port_scan::tcp_scan, + query, service_scan::service_scan::scan_services, }; -const BATCH_SIZE: usize = 4096; +const HILBERT_VIS_SIZE: usize = 256; /// A fictional versioning CLI #[derive(Debug, Parser)] @@ -34,6 +38,13 @@ enum Commands { Scan { /// List of remote servers hosts: String, + + /// Size of block of IPs to scan + #[arg(short, long, default_value_t = 4096)] + batch_size: usize, + /// The top N most common ports to scan + #[arg(short, long, default_value_t = 150)] + n_ports: usize, /// Timeout for requests #[arg(short, long, default_value_t = 3000)] timeout_ms: u64, @@ -54,6 +65,31 @@ enum Commands { Rescan { /// The search query query: Vec, + + /// Size of block of IPs to scan + #[arg(short, long, default_value_t = 4096)] + batch_size: usize, + /// The top N most common ports to scan + #[arg(short, long, default_value_t = 150)] + n_ports: usize, + /// Timeout for requests + #[arg(short, long, default_value_t = 3000)] + timeout_ms: u64, + /// Delay between icmp echo requests + #[arg(short, long, default_value_t = 80)] + ping_delay_micros: u64, + /// Delay between tcp syn packets + #[arg(short, long, default_value_t = 100)] + syn_tcp_delay_micros: u64, + }, + /// Scans random services + Random { + /// Size of block of IPs to scan + #[arg(short, long, default_value_t = 4096)] + batch_size: usize, + /// The top N most common ports to scan + #[arg(short, long, default_value_t = 150)] + n_ports: usize, /// Timeout for requests #[arg(short, long, default_value_t = 3000)] timeout_ms: u64, @@ -73,6 +109,8 @@ fn main() -> Result<(), Box> { match args.command { Commands::Scan { hosts, + batch_size, + n_ports, timeout_ms, ping_delay_micros, syn_tcp_delay_micros, @@ -80,8 +118,10 @@ fn main() -> Result<(), Box> { let hosts = parse_ip_targets(&hosts)?; scan( - database, + batch_size, + &database, hosts, + ports::PORTS[0..n_ports].to_vec(), Duration::from_millis(timeout_ms), Duration::from_micros(ping_delay_micros), Duration::from_micros(syn_tcp_delay_micros), @@ -89,17 +129,42 @@ fn main() -> Result<(), Box> { } Commands::Rescan { query, + batch_size, + n_ports, timeout_ms, ping_delay_micros, syn_tcp_delay_micros, } => { - rescan( - database, - query, - Duration::from_millis(timeout_ms), - Duration::from_micros(ping_delay_micros), - Duration::from_micros(syn_tcp_delay_micros), - )?; + let start = Instant::now(); + if let Ok(query) = query::search(query) { + let results = database.search(query); + if let Ok(results) = results { + let len = results.len(); + + let mut hosts: Vec = Vec::new(); + + for result in results { + println!("{}", result.to_string()); + hosts.push(IpAddr::from_str(result.ip.as_str()).unwrap()); + } + println!("{} results in {}ms", len, start.elapsed().as_millis()); + + hosts.sort(); + hosts.dedup(); + hosts.shuffle(&mut rng()); + + scan( + batch_size, + &database, + hosts, + ports::PORTS[0..n_ports].to_vec(), + // (1..65535).collect(), + Duration::from_millis(timeout_ms), + Duration::from_micros(ping_delay_micros), + Duration::from_micros(syn_tcp_delay_micros), + )?; + } + } } Commands::Search { query } => { let start = Instant::now(); @@ -107,6 +172,7 @@ fn main() -> Result<(), Box> { let results = database.search(query); if let Ok(results) = results { let len = results.len(); + for result in results { println!("{}", result.to_string()); } @@ -114,100 +180,73 @@ fn main() -> Result<(), Box> { } } } + Commands::Random { + batch_size, + n_ports, + timeout_ms, + ping_delay_micros, + syn_tcp_delay_micros, + } => loop { + let hosts = generate_random_ipv4_addresses( + batch_size, + vec![ + "0.0.0.0/8", + "10.0.0.0/8", + "100.64.0.0/10", + "127.0.0.0/8", + "169.254.0.0/16", + "172.16.0.0/12", + "192.0.0.0/24", + "192.0.0.0/29", + "192.0.0.170/32", + "192.0.0.171/32", + "192.0.2.0/24", + "192.88.99.0/24", + "192.168.0.0/16", + "198.18.0.0/15", + "198.51.100.0/24", + "203.0.113.0/24", + "240.0.0.0/4", + "255.255.255.255/32", + "131.215.0.0/16", + "134.4.0.0/16", + "192.12.19.0/24", + "192.31.43.0/24", + "192.41.208.0/24", + "192.43.243.0/24", + "192.54.249.0/24", + ], + ); + + scan( + batch_size, + &database, + hosts, + ports::PORTS[0..n_ports].to_vec(), + Duration::from_millis(timeout_ms), + Duration::from_micros(ping_delay_micros), + Duration::from_micros(syn_tcp_delay_micros), + )?; + }, _ => {} } Ok(()) } -const PORTS_1: [i32; 713] = [ - 1337, 2000, 2001, 2006, 2012, 2018, 2024, 6969, 7777, 10000, 10001, 10002, 10003, 10004, 10005, - 10006, 10007, 10008, 10009, 10010, 10020, 10030, 10040, 10050, 10060, 10070, 10080, 10090, - 10100, 10110, 10120, 10140, 10150, 10160, 10200, 10230, 10250, 10400, 10600, 10800, 11000, - 11200, 11400, 11600, 11800, 12000, 12200, 12345, 12400, 12600, 12800, 13000, 13200, 13400, - 13600, 13800, 14000, 14200, 14400, 14600, 14800, 15000, 15200, 15400, 15600, 15800, 16000, - 16200, 16400, 16600, 16800, 17000, 17200, 17400, 17600, 17800, 18000, 18200, 18400, 18600, - 18800, 19000, 19132, 19200, 19400, 19600, 19800, 20000, 20001, 20002, 20200, 20400, 20600, - 20800, 21000, 21200, 21400, 21600, 21800, 22000, 22200, 22222, 22400, 22600, 22800, 23000, - 23200, 23400, 23600, 24000, 24200, 24400, 24600, 24800, 25000, 25001, 25003, 25004, 25073, - 25110, 25126, 25200, 25216, 25400, 25417, 25500, 25501, 25502, 25503, 25504, 25505, 25506, - 25507, 25510, 25511, 25512, 25515, 25520, 25522, 25525, 25535, 25541, 25542, 25545, 25550, - 25551, 25552, 25553, 25554, 25555, 25556, 25558, 25559, 25560, 25561, 25562, 25563, 25564, - 25565, 25566, 25567, 25568, 25569, 25570, 25571, 25572, 25573, 25574, 25575, 25576, 25577, - 25578, 25579, 25580, 25581, 25582, 25583, 25584, 25585, 25586, 25587, 25588, 25589, 25590, - 25591, 25592, 25593, 25594, 25595, 25596, 25597, 25598, 25599, 25600, 25601, 25602, 25603, - 25604, 25605, 25606, 25607, 25608, 25609, 25610, 25611, 25612, 25613, 25614, 25615, 25616, - 25617, 25618, 25619, 25620, 25621, 25622, 25623, 25624, 25625, 25626, 25627, 25628, 25629, - 25630, 25631, 25632, 25633, 25634, 25635, 25636, 25637, 25638, 25639, 25640, 25641, 25642, - 25643, 25644, 25645, 25646, 25647, 25648, 25649, 25650, 25651, 25652, 25653, 25654, 25655, - 25656, 25657, 25658, 25659, 25660, 25661, 25662, 25663, 25664, 25665, 25666, 25667, 25668, - 25669, 25670, 25671, 25672, 25673, 25674, 25675, 25676, 25677, 25678, 25679, 25680, 25681, - 25682, 25683, 25684, 25685, 25686, 25687, 25688, 25689, 25690, 25692, 25693, 25695, 25696, - 25697, 25700, 25702, 25705, 25708, 25714, 25720, 25725, 25726, 25732, 25738, 25744, 25745, - 25750, 25756, 25762, 25765, 25768, 25774, 25780, 25785, 25786, 25792, 25798, 25800, 25804, - 25805, 25810, 25816, 25822, 25825, 25828, 25834, 25840, 25845, 25846, 25852, 25858, 25864, - 25865, 25870, 25876, 25882, 25885, 25888, 25894, 25900, 25905, 25906, 25918, 25924, 25925, - 25930, 25936, 25942, 25945, 25948, 25954, 25965, 25966, 25972, 25978, 25984, 25985, 25990, - 25996, 26000, 26002, 26005, 26008, 26014, 26020, 26025, 26026, 26032, 26038, 26044, 26045, - 26056, 26062, 26065, 26068, 26080, 26085, 26092, 26098, 26104, 26105, 26116, 26122, 26125, - 26134, 26140, 26145, 26146, 26158, 26164, 26165, 26170, 26176, 26185, 26188, 26194, 26200, - 26205, 26212, 26225, 26230, 26236, 26242, 26245, 26248, 26254, 26265, 26266, 26278, 26284, - 26285, 26296, 26302, 26305, 26320, 26325, 26326, 26332, 26338, 26344, 26345, 26350, 26362, - 26365, 26380, 26385, 26386, 26392, 26398, 26400, 26404, 26405, 26425, 26445, 26465, 26476, - 26485, 26505, 26525, 26545, 26565, 26566, 26585, 26600, 26605, 26625, 26645, 26665, 26685, - 26705, 26725, 26745, 26765, 26785, 26800, 26805, 26825, 26845, 26865, 26885, 26905, 26925, - 26945, 26965, 26985, 27000, 27005, 27015, 27025, 27065, 27085, 27165, 27200, 27265, 27365, - 27400, 27465, 27565, 27600, 27665, 27765, 27800, 27865, 27965, 28000, 28065, 28165, 28265, - 28365, 28400, 28465, 28565, 28665, 28765, 28800, 28865, 28965, 29000, 29065, 29165, 29200, - 29265, 29365, 29400, 29465, 29565, 29600, 29665, 29765, 29800, 29865, 29965, 30000, 30001, - 30002, 30015, 30065, 30165, 30200, 30265, 30365, 30400, 30465, 30565, 30600, 30665, 30765, - 30800, 30865, 30965, 31000, 31065, 31165, 31200, 31265, 31365, 31400, 31465, 31565, 31665, - 31765, 31800, 31865, 31965, 32000, 32065, 32165, 32265, 32365, 32400, 32465, 32565, 32600, - 32665, 32765, 32800, 32865, 32965, 33000, 33065, 33165, 33200, 33265, 33365, 33400, 33465, - 33565, 33600, 33665, 33765, 33800, 33865, 33965, 34000, 34065, 34165, 34200, 34265, 34365, - 34400, 34465, 34565, 34600, 34665, 34800, 35000, 35400, 35565, 35600, 35800, 36000, 36400, - 36600, 37000, 37600, 37800, 38000, 38200, 38600, 38800, 39000, 39400, 40000, 40001, 40400, - 40600, 41000, 41200, 41400, 41600, 42000, 42069, 42200, 42400, 42600, 42800, 43000, 43600, - 43800, 44000, 44200, 44400, 44600, 44800, 44955, 44956, 44957, 44958, 44959, 44961, 45000, - 45200, 45400, 45600, 45800, 46000, 46200, 46400, 46600, 46800, 47000, 47200, 47400, 47600, - 47800, 48000, 48200, 48400, 48800, 49400, 49600, 49800, 50000, 50001, 50002, 50200, 50400, - 50600, 51000, 51200, 51400, 51600, 51800, 52000, 52200, 52400, 52600, 52800, 53200, 53800, - 54000, 54200, 54600, 54800, 55000, 55400, 55555, 55600, 55800, 56000, 56200, 56400, 56600, - 57200, 57400, 57600, 57800, 58200, 58600, 58800, 59000, 59200, 59400, 59800, 60200, 60400, - 60600, 60800, 61000, 61200, 61400, 61600, 62000, 62200, 62400, 62800, 63000, 63200, 63400, - 63600, 63800, 64000, 64200, 64400, 64600, 64800, 65000, 65200, -]; - -const PORTS_2: [i32; 171] = [ - 10000, 10010, 10020, 19132, 25500, 25501, 25555, 25560, 25561, 25562, 25563, 25564, 25565, - 25566, 25567, 25568, 25569, 25570, 25571, 25572, 25573, 25574, 25575, 25576, 25577, 25578, - 25579, 25580, 25581, 25582, 25583, 25584, 25585, 25586, 25587, 25588, 25589, 25590, 25591, - 25592, 25593, 25594, 25595, 25596, 25597, 25598, 25599, 25600, 25601, 25602, 25603, 25604, - 25605, 25606, 25607, 25608, 25609, 25610, 25611, 25612, 25613, 25614, 25615, 25616, 25617, - 25618, 25619, 25620, 25621, 25622, 25623, 25624, 25625, 25626, 25627, 25628, 25629, 25630, - 25631, 25632, 25633, 25635, 25636, 25642, 25645, 25648, 25665, 25666, 25685, 25700, 25765, - 25865, 25965, 26065, 26165, 26265, 26365, 26465, 26565, 26665, 26765, 26865, 26965, 27065, - 27165, 27265, 27365, 27465, 27565, 27665, 27765, 27865, 27965, 28065, 28165, 28265, 28365, - 28465, 28565, 28665, 28765, 28865, 28965, 29065, 29165, 29265, 29365, 29465, 29565, 29665, - 29765, 29865, 29965, 30000, 30065, 30165, 30265, 30365, 30465, 30565, 30665, 30765, 30865, - 30965, 31065, 31165, 31265, 31365, 31465, 31565, 31665, 31765, 31865, 31965, 32065, 32165, - 32265, 32365, 32465, 32565, 32665, 32765, 32865, 32965, 33065, 33165, 33265, 33365, 33565, - 33665, 44955, -]; - fn scan( - database: ResultDatabase, + batch_size: usize, + database: &ResultDatabase, hosts: Vec, + ports: Vec, timeout: Duration, ping_delay: Duration, tcp_delay: Duration, ) -> Result<(), Box> { - // Parse the targets into IP addresses - // let hosts = parse_ip_targets(&hosts)?; + let start_time = Instant::now(); + let mut server_count = 0; - // println!("{:?}", hosts); - - let chunks = hosts.chunks(BATCH_SIZE); + let chunks = hosts.chunks(batch_size); let num_chunks = chunks.len(); for (i, hosts) in chunks.enumerate() { let hosts = hosts.to_vec(); @@ -224,104 +263,19 @@ fn scan( up_hosts.len() ); - let tcp_results = tcp_scan::tcp_scan(up_hosts, PORTS_2.to_vec(), timeout, tcp_delay); + let tcp_results = tcp_scan::tcp_scan(up_hosts, &ports, timeout, tcp_delay); println!("Finished port scan"); let service_results = scan_services(tcp_results, min(50, up_len), timeout); println!("Finished service scan"); + server_count += service_results.len(); let _ = database.add_data_row(service_results); } - Ok(()) -} - -fn rescan( - database: ResultDatabase, - query: Vec, - timeout: Duration, - ping_delay: Duration, - tcp_delay: Duration, -) -> Result<(), Box> { - let start = Instant::now(); - if let Ok(query) = query::search(query) { - let results = database.search(query); - if let Ok(results) = results { - let len = results.len(); - - let mut hosts: Vec = Vec::new(); - - for result in results { - println!("{}", result.to_string()); - hosts.push(IpAddr::from_str(result.ip.as_str()).unwrap()); - } - println!("{} results in {}ms", len, start.elapsed().as_millis()); - - hosts.sort(); - hosts.dedup(); - hosts.shuffle(&mut rng()); - - scan(database, hosts, timeout, ping_delay, tcp_delay)?; - } - } + println!("Total Servers: {}", server_count); + let elapsed = start_time.elapsed().as_secs_f32() / 60.; + println!("Total Elapsed: {} min", elapsed); + println!("Rate: {} servers/min", (server_count as f32 / elapsed)); Ok(()) } - -fn print_help(arg: Option<&str>) { - println!( - "{}", - match arg { - None => { - "rust-scan help menu -Commands: - scan - scan a block of addresses and check for online using icmp echo - search - Search database - help (command) - Print help" - } - Some("scan") => { - "Usage scan (type) - -Example: scan ping 127.0.0.0/8 -Example: scan 12.34.0.0-12.34.56.78,127.0.0.1 - -scan a block of addresses using diffrent methods - -- scan ping -Scan a block of addresses and check if their online - -- scan tcp -Scan a block of addresses and check if their online, then scan and check what ports are open - -- scan service -Scan a block of addresses and check if their online, then scan to check what ports are open, then scan to check what services are running and record responses - -- scan -Same as scan service" - } - - Some("search") => { - "Usage: search -Example: search ssh:raspbian -Example: search port:80,443 http-nginx https-nginx -Example: search port-8081 https:favicon -Example: search google -Example: search port=22,80,443 - -The format of the search is a list of tags that include the service or port followed by an equator, or a plain text search - -There are four types of equators - -\":\" or \"+\" - If the result contains an item -\"-\" - If the result does not contain an item -\"=\" - If the result is exactly equal to an item -\"!=\" - If the result is exactly not equal to an item - -" - } - Some(_) => { - print_help(None); - "Invalid Command!" - } - } - ); -} diff --git a/src/parse_ip_range.rs b/src/parse_ip_range.rs index 813e1b1..ca34055 100644 --- a/src/parse_ip_range.rs +++ b/src/parse_ip_range.rs @@ -3,7 +3,8 @@ use std::{ str::FromStr, }; -use rand::{rng, seq::SliceRandom}; +use pnet::ipnetwork::IpNetwork; +use rand::{Rng, rng, seq::SliceRandom}; // static MAX_HOSTS: u32 = 1024; @@ -119,3 +120,39 @@ fn parse_ip_range(range: &str, ips: &mut Vec) -> Result<(), Box) -> Vec { + let mut result = Vec::with_capacity(count); + let mut rng = rand::rng(); + + // Parse the CIDR blocks + let excluded_networks: Vec = excluded_cidrs + .iter() + .filter_map(|cidr| IpNetwork::from_str(cidr).ok()) + .collect(); + + while result.len() < count { + // Generate a random IPv4 address + let ip = Ipv4Addr::new( + rng.random_range(0..=255), + rng.random_range(0..=255), + rng.random_range(0..=255), + rng.random_range(0..=255), + ); + + // Convert to IpAddr for use with IpNetwork + let ip_addr = IpAddr::V4(ip); + + // Check if IP is in any of the excluded networks + let is_excluded = excluded_networks + .iter() + .any(|network| network.contains(ip_addr)); + + if !is_excluded { + // println!("{}", ip_addr); + result.push(ip_addr); + } + } + + result +} diff --git a/src/port_scan/tcp_scan.rs b/src/port_scan/tcp_scan.rs index a53894b..52c011f 100644 --- a/src/port_scan/tcp_scan.rs +++ b/src/port_scan/tcp_scan.rs @@ -23,7 +23,7 @@ fn std_to_pnet_ipv4(previous: &IpAddr) -> Ipv4Addr { // Main scanning function pub fn tcp_scan( targets: Vec, - ports: Vec, + ports: &Vec, timeout: Duration, tcp_delay: Duration, ) -> Vec { @@ -151,7 +151,7 @@ pub fn tcp_scan( let sender_finished_sending_time = Arc::clone(&finished_sending_time); let sender_port_count = Arc::clone(&port_count); for target in &targets { - for port in &ports { + for port in ports { // let source_ip = Ipv4Addr::from_bits(random_range(0..=(0xffffffff))); let source_port: u16 = random_range(1..=65535); // println!("{}", source_ip.to_string()); diff --git a/src/ports.rs b/src/ports.rs index e69de29..f563126 100644 --- a/src/ports.rs +++ b/src/ports.rs @@ -0,0 +1,180 @@ +pub const PORTS: [u16; 2354] = [ + 25565, 25566, 25567, 25568, 25570, 25569, 25577, 25571, 25580, 25576, 25572, 25573, 25585, + 25575, 25578, 25574, 25583, 25581, 25582, 25584, 25579, 25588, 25586, 25587, 25589, 25590, + 25591, 25595, 25594, 25593, 25592, 25600, 25599, 25596, 25598, 25597, 25601, 25602, 25605, + 25564, 25603, 25606, 25604, 25665, 25610, 25607, 25612, 25560, 25608, 25611, 25609, 25613, + 25614, 25765, 25618, 25555, 25615, 25616, 25865, 25617, 26665, 26565, 25965, 25625, 26065, + 26765, 27065, 30165, 10000, 26265, 25619, 26465, 26865, 26165, 26365, 25561, 27365, 26965, + 27265, 27465, 27165, 27565, 25623, 25621, 25624, 25700, 27865, 27665, 27765, 28065, 25563, + 28165, 25620, 28265, 28365, 27965, 28465, 25622, 30065, 28565, 28765, 10010, 25645, 29565, + 25630, 28665, 28865, 29965, 31365, 19132, 25636, 28965, 29465, 29865, 30965, 44955, 32165, + 25626, 29065, 25500, 30765, 25685, 29365, 25666, 29665, 25562, 30865, 29165, 30265, 31865, + 31965, 30365, 25627, 25642, 30565, 31765, 31265, 32365, 32465, 30665, 31065, 32265, 32965, + 29765, 31465, 25635, 31665, 32065, 32565, 32865, 33665, 25629, 30465, 31165, 29265, 32665, + 25628, 33065, 25648, 32765, 10020, 25501, 30000, 31565, 25631, 33365, 25632, 33165, 33265, + 33565, 25633, 25660, 33465, 33765, 10030, 25678, 33865, 44956, 25634, 25638, 25639, 25654, + 35565, 25637, 25650, 33965, 25672, 10070, 25000, 25684, 34065, 34165, 25502, 25696, 25805, + 34265, 25541, 2000, 25690, 10050, 25640, 25641, 10060, 25644, 10040, 25725, 25785, 50000, + 25652, 25655, 25885, 25705, 25745, 25925, 20000, 25845, 26200, 11000, 12600, 25073, 42069, + 44957, 11400, 25647, 25649, 10800, 25653, 11800, 25646, 10001, 25651, 25643, 10090, 12800, + 26000, 10600, 25657, 25708, 25800, 30001, 15000, 25714, 25825, 25985, 10400, 25556, 25656, + 25675, 25945, 10200, 11200, 12200, 16200, 25720, 13200, 25661, 25702, 26025, 34365, 44958, + 14200, 25503, 25905, 11600, 25545, 25659, 13800, 14000, 22600, 26005, 26185, 1337, 10100, + 13400, 17000, 25126, 25677, 30015, 10002, 10120, 12345, 15800, 17800, 21800, 25510, 25664, + 25900, 13000, 13600, 15400, 26085, 26105, 26225, 27000, 34465, 40000, 14400, 20200, 25658, + 25663, 25689, 25693, 25738, 25798, 26125, 45200, 10080, 20001, 20002, 25667, 25726, 25936, + 26600, 28800, 39000, 14800, 15600, 16600, 17400, 18200, 21000, 25662, 25682, 25768, 25774, + 26445, 12400, 16000, 16400, 19200, 21600, 22200, 23200, 25001, 25668, 26285, 26400, 37800, + 15200, 18400, 19400, 25400, 25559, 26045, 31000, 41000, 42200, 50001, 18600, 25671, 25744, + 25792, 26145, 26245, 27600, 52400, 62800, 20800, 24200, 25511, 25683, 25750, 25756, 25762, + 25852, 29200, 33000, 34665, 36000, 49800, 59800, 63400, 10110, 20600, 21400, 24400, 24800, + 25417, 25505, 25670, 25681, 25948, 26002, 26205, 26425, 28000, 51400, 52800, 55400, 10004, + 10160, 14600, 17200, 19000, 25110, 25216, 25550, 25551, 25552, 25669, 25804, 25810, 25816, + 25924, 26585, 26605, 33400, 34565, 38000, 45600, 45800, 57400, 61200, 2006, 6969, 10007, 16800, + 18800, 25732, 25786, 26405, 26485, 29400, 30002, 32600, 34000, 41600, 45000, 47200, 47600, + 48800, 49400, 2012, 10003, 24600, 25200, 25504, 25515, 25673, 25828, 25864, 25930, 26008, + 26164, 26345, 26685, 27400, 27800, 30800, 31400, 35600, 36600, 44200, 44959, 46200, 50400, + 52600, 55600, 56600, 60200, 10150, 12000, 22400, 23600, 24000, 25554, 25674, 25676, 25846, + 25882, 25918, 25966, 25990, 25996, 26176, 26212, 26945, 31200, 31800, 34200, 42400, 42600, + 46800, 47000, 49600, 50002, 54200, 10140, 20400, 21200, 25506, 25525, 25679, 25680, 25687, + 25695, 25840, 25858, 25888, 25972, 26032, 26044, 26098, 26122, 26305, 26332, 26625, 26725, + 26925, 27025, 29600, 33600, 33800, 34400, 34800, 37000, 41400, 48200, 50200, 51800, 59200, + 64800, 10005, 18000, 25697, 26080, 26170, 26325, 26385, 26386, 26398, 26404, 26745, 33200, + 40001, 44961, 50600, 55000, 57800, 58200, 59400, 60400, 65000, 7777, 19800, 23000, 25507, + 25553, 25780, 25876, 25954, 25978, 25984, 26020, 26038, 26056, 26188, 26194, 26344, 26380, + 26392, 26505, 26525, 26785, 26805, 26845, 27015, 32400, 38600, 43600, 44000, 44600, 45400, + 48400, 52200, 55555, 56000, 59000, 60600, 61600, 63800, 64200, 64400, 2024, 10006, 10250, + 19600, 22000, 22222, 25520, 25535, 25686, 26068, 26092, 26146, 26296, 26705, 26985, 27200, + 28400, 32800, 35000, 37600, 38800, 39400, 41200, 47400, 47800, 51200, 53800, 54600, 55800, + 58600, 60800, 62400, 63000, 63600, 10230, 23400, 25692, 25822, 25834, 25894, 25942, 26026, + 26062, 26104, 26116, 26134, 26140, 26230, 26302, 26476, 26545, 26566, 26645, 26825, 30400, + 32000, 34600, 35800, 40400, 40600, 46000, 51000, 54000, 61000, 61400, 62000, 64000, 64600, + 65200, 2001, 10009, 25004, 25512, 25522, 25558, 25688, 25870, 26014, 26236, 26284, 26326, + 26362, 26800, 27005, 29800, 30200, 30600, 38200, 42800, 43000, 43800, 44800, 46600, 51600, + 52000, 53200, 56200, 57600, 62200, 2018, 10008, 17600, 22800, 25003, 25542, 25906, 26158, + 26242, 26248, 26254, 26266, 26278, 26320, 26338, 26350, 26885, 26905, 27085, 29000, 35400, + 36400, 42000, 44400, 46400, 48000, 54800, 56400, 57200, 58800, 63200, 2030, 10130, 10190, + 11111, 19133, 21040, 25530, 25557, 25698, 25912, 25999, 26074, 26128, 26152, 26260, 26314, + 26458, 34965, 35566, 36800, 40800, 41800, 53000, 53400, 53600, 55200, 58000, 2222, 10260, + 25005, 25514, 25691, 25694, 26050, 26086, 26182, 26218, 26368, 26422, 26464, 26518, 26560, + 28200, 28600, 30066, 34765, 35200, 36200, 37400, 39200, 40200, 49000, 50800, 58400, 60000, + 61800, 2023, 10013, 10014, 10210, 19134, 23456, 23800, 25002, 25752, 25960, 26206, 26224, + 26290, 26308, 27018, 30003, 35165, 35365, 42617, 43200, 49200, 57000, 65400, 2002, 10015, + 10220, 10410, 19135, 25232, 25531, 25701, 25707, 25735, 26272, 26356, 26470, 26666, 27105, + 27145, 32200, 34865, 37200, 38400, 54400, 59600, 62600, 2036, 2042, 2060, 10012, 10016, 10170, + 20003, 20004, 25509, 25513, 25521, 25524, 25529, 25539, 25699, 25715, 25755, 25869, 26110, + 26410, 26416, 26452, 26482, 30120, 44960, 56800, 1111, 2137, 10180, 10240, 10290, 10330, 25516, + 25518, 25526, 25536, 25544, 25710, 25713, 25716, 25734, 25748, 25764, 25790, 26428, 26446, + 26500, 26506, 27021, 27033, 27045, 30004, 30067, 31600, 39800, 40099, 48600, 5000, 6000, 6666, + 8999, 10011, 10017, 10019, 19136, 25508, 25523, 25528, 25704, 25731, 25766, 25781, 25795, + 26374, 26494, 26542, 27026, 27040, 30010, 35265, 39600, 40002, 43400, 44964, 2048, 2054, 2066, + 2102, 2252, 8080, 10270, 10280, 10350, 10430, 21100, 24565, 25420, 25517, 25533, 25718, 25723, + 25733, 25771, 25775, 25778, 25855, 25892, 26434, 26578, 26590, 27019, 27032, 27185, 30005, + 30135, 30225, 2072, 2556, 3000, 8000, 10300, 10370, 10380, 19137, 20006, 25465, 25537, 25547, + 25548, 25549, 25703, 25706, 25728, 25729, 25772, 25827, 25841, 26001, 26488, 26512, 26530, + 26536, 26554, 26584, 27002, 27017, 27022, 27029, 27031, 27036, 30068, 35865, 44962, 45565, + 50004, 2003, 2084, 2120, 2138, 2186, 2203, 2276, 8888, 10022, 10023, 10027, 10033, 10360, + 10490, 11451, 19140, 20007, 24454, 25006, 25717, 25721, 25730, 25740, 25749, 25757, 25782, + 25802, 25866, 25920, 26602, 26614, 26656, 27001, 27016, 27034, 27125, 30028, 30235, 33333, + 35065, 35765, 36165, 42658, 44444, 44963, 1, 2005, 2078, 2108, 2114, 2180, 2234, 2240, 3001, + 8001, 10024, 10035, 10340, 10440, 19139, 20008, 20031, 25008, 25010, 25543, 25712, 25737, + 25741, 25763, 25839, 25856, 25868, 25873, 25880, 25995, 26440, 26524, 26548, 26596, 26608, + 27027, 27028, 27030, 27110, 27705, 28001, 50003, 80, 2126, 2201, 2202, 2213, 2228, 4000, 5001, + 6001, 9999, 10018, 10025, 10029, 10320, 10460, 10470, 10500, 15565, 19141, 21125, 23333, 25100, + 25239, 25300, 25540, 25711, 25719, 25736, 25758, 25767, 25783, 25789, 25796, 25815, 25823, + 25835, 25844, 25847, 25848, 25883, 25895, 25902, 25915, 25951, 25975, 26055, 26572, 27035, + 27205, 27225, 29999, 30006, 30007, 43033, 44965, 50005, 1028, 2007, 2132, 2156, 2200, 2224, + 2247, 5002, 6002, 6003, 8002, 8008, 9001, 10028, 10031, 10420, 10510, 10560, 12012, 13226, + 19130, 19138, 20005, 20700, 25007, 25020, 25034, 25105, 25402, 25534, 25538, 25546, 25709, + 25743, 25746, 25753, 25754, 25761, 25773, 25784, 25788, 25793, 25794, 25809, 25820, 25826, + 25830, 25837, 25850, 25862, 25863, 25872, 25877, 25890, 25911, 25932, 25953, 25989, 25998, + 27003, 27020, 27037, 27042, 27050, 27070, 27285, 28888, 35665, 35679, 41059, 55565, 56552, + 1001, 2090, 2192, 2210, 2226, 2233, 2236, 2237, 2250, 2258, 2269, 2270, 2330, 2500, 3002, 4001, + 4002, 5555, 5565, 8004, 9596, 10021, 10310, 10480, 10530, 10590, 18595, 20020, 20500, 21041, + 21121, 25012, 25015, 25017, 25023, 25024, 25368, 25404, 25527, 25722, 25724, 25727, 25742, + 25747, 25751, 25760, 25777, 25791, 25799, 25814, 25821, 25824, 25832, 25842, 25851, 25857, + 25860, 25891, 25904, 25909, 25917, 25923, 25938, 25952, 25955, 25958, 25962, 25994, 26009, + 26115, 26610, 27023, 27024, 27048, 29311, 30185, 30201, 35465, 35965, 41588, 44966, 45925, + 50006, 61328, 1145, 1370, 2011, 2014, 2096, 2144, 2168, 2198, 2204, 2206, 2216, 2246, 2264, + 2277, 2312, 2318, 2402, 4444, 5006, 7778, 8003, 8005, 9005, 10026, 10034, 10101, 10390, 10570, + 10610, 10710, 12001, 16969, 19147, 19150, 19155, 19217, 19235, 20011, 20012, 20018, 20021, + 20025, 20300, 21111, 21130, 23020, 23334, 25009, 25036, 25162, 25314, 25316, 25373, 25426, + 25532, 25739, 25770, 25797, 25806, 25808, 25812, 25813, 25831, 25833, 25838, 25871, 25875, + 25879, 25881, 25884, 25886, 25889, 25913, 25931, 25935, 25943, 25961, 25964, 25968, 25974, + 25976, 25983, 25987, 26035, 26075, 26175, 26195, 26528, 26620, 26638, 26680, 26704, 26900, + 26969, 27038, 27044, 27051, 27120, 27325, 27445, 28654, 29124, 30011, 30013, 30025, 30100, + 30150, 30160, 30203, 30206, 34001, 35570, 37365, 41253, 42489, 52115, 55023, 60001, 64946, 2, + 100, 1030, 2004, 2013, 2022, 2031, 2098, 2100, 2150, 2205, 2225, 2249, 2253, 2254, 2257, 2262, + 2280, 2306, 2324, 2360, 2740, 3003, 3909, 3918, 4005, 5005, 6012, 6027, 6765, 7009, 8007, 8010, + 8101, 9010, 9996, 10032, 10550, 10580, 10620, 10630, 10660, 10720, 10760, 12010, 12013, 12018, + 12019, 12027, 12321, 12738, 12744, 13786, 14003, 14043, 14487, 14712, 15199, 15490, 15684, + 15702, 17500, 17528, 18007, 18053, 19108, 19145, 19234, 20015, 20055, 20056, 20560, 21085, + 21596, 23565, 24100, 24315, 24715, 25011, 25014, 25016, 25022, 25027, 25030, 25037, 25038, + 25039, 25045, 25058, 25101, 25123, 25159, 25184, 25192, 25222, 25236, 25302, 25312, 25339, + 25345, 25384, 25399, 25432, 25456, 25466, 25469, 25486, 25759, 25769, 25776, 25779, 25787, + 25811, 25817, 25818, 25836, 25853, 25878, 25887, 25896, 25899, 25907, 25910, 25914, 25916, + 25926, 25927, 25939, 25941, 25963, 25969, 25973, 25979, 25988, 26004, 26007, 26015, 26031, + 26036, 26040, 26053, 26073, 26141, 26161, 26174, 26192, 26361, 26390, 26423, 26439, 26459, + 26489, 26495, 26644, 26650, 26655, 26662, 26676, 26681, 26698, 26809, 26830, 27039, 27041, + 27088, 27315, 27505, 27515, 27777, 27825, 27878, 28002, 28020, 28201, 28208, 29375, 29875, + 30012, 30014, 30018, 30030, 30070, 30077, 30175, 30240, 30376, 30674, 31001, 31500, 31501, + 32048, 32688, 32798, 32863, 33268, 35507, 35568, 36065, 36265, 37782, 38281, 38298, 38965, + 40003, 40004, 40318, 40904, 41580, 42770, 43718, 43970, 44212, 44968, 45002, 45003, 45703, + 45854, 46003, 46023, 50013, 50021, 50154, 50477, 51143, 51451, 53139, 54321, 54503, 54921, + 55270, 55977, 57174, 58454, 59720, 60100, 63025, 64171, 420, 666, 1000, 1025, 1026, 1031, 1215, + 1234, 1280, 1850, 2009, 2021, 2025, 2077, 2082, 2115, 2209, 2212, 2217, 2221, 2223, 2232, 2241, + 2242, 2243, 2245, 2248, 2256, 2259, 2263, 2272, 2278, 2281, 2282, 2292, 2294, 2296, 2298, 2300, + 2304, 2348, 2366, 2378, 2414, 2426, 2525, 2528, 2555, 2564, 3011, 3036, 3131, 3192, 3200, 3333, + 3605, 3782, 4004, 4013, 4049, 4193, 4242, 4545, 4861, 5010, 5175, 5443, 5656, 5842, 5991, 6004, + 6005, 6009, 6144, 6265, 6699, 6864, 7000, 7002, 7032, 7793, 7816, 8006, 8028, 8118, 8194, 8210, + 8211, 8405, 8962, 9000, 9114, 9485, 9848, 10036, 10037, 10038, 10041, 10056, 10059, 10107, + 10222, 10325, 10520, 10540, 10650, 10770, 10780, 10790, 10820, 10830, 10980, 11090, 11099, + 11173, 11710, 11728, 11931, 11960, 12002, 12007, 12015, 12016, 12020, 12026, 12028, 12300, + 12341, 12371, 12441, 12552, 12945, 12981, 13001, 13048, 13094, 13174, 13302, 13364, 13458, + 13686, 13746, 13777, 13979, 14068, 14215, 14249, 14294, 14306, 14690, 14733, 15260, 15427, + 15495, 15568, 15581, 15821, 16025, 16343, 16346, 16389, 16568, 16656, 16891, 16916, 16960, + 17110, 17205, 17240, 17424, 18153, 18165, 18181, 18262, 18312, 18340, 18342, 18684, 18896, + 18913, 18923, 19001, 19131, 19143, 19146, 19153, 19173, 19184, 19189, 19232, 19255, 19275, + 19331, 19337, 19372, 19391, 19543, 19605, 19686, 19746, 19812, 20010, 20016, 20022, 20023, + 20026, 20030, 20035, 20042, 20044, 20066, 20091, 20100, 20107, 20120, 20130, 20145, 20180, + 20216, 20224, 20246, 20265, 20419, 20528, 20708, 20780, 20803, 20874, 21005, 21010, 21101, + 21116, 21186, 21300, 21307, 21341, 21402, 21484, 21536, 21565, 21613, 21693, 21713, 21723, + 21795, 22100, 22300, 22301, 22345, 22355, 22561, 22565, 22597, 22613, 22685, 22706, 22768, + 22922, 23001, 23015, 23221, 23267, 23289, 23381, 23394, 23438, 23457, 23461, 23500, 23518, + 23557, 23613, 23656, 24027, 24064, 24113, 24322, 24444, 24455, 24464, 24523, 24629, 24666, + 24680, 24777, 24921, 24975, 25018, 25025, 25031, 25061, 25065, 25066, 25086, 25089, 25094, + 25097, 25111, 25116, 25132, 25136, 25147, 25160, 25173, 25176, 25196, 25202, 25205, 25220, + 25242, 25265, 25292, 25296, 25299, 25310, 25327, 25333, 25336, 25337, 25340, 25362, 25371, + 25375, 25376, 25383, 25387, 25401, 25403, 25410, 25415, 25454, 25470, 25487, 25801, 25843, + 25849, 25867, 25901, 25921, 25929, 25934, 25944, 25950, 25956, 25967, 25981, 25993, 25997, + 26011, 26013, 26042, 26047, 26048, 26054, 26088, 26095, 26103, 26106, 26118, 26123, 26126, + 26127, 26142, 26156, 26162, 26215, 26219, 26226, 26227, 26234, 26240, 26255, 26268, 26275, + 26279, 26281, 26288, 26294, 26295, 26357, 26369, 26427, 26441, 26449, 26450, 26474, 26475, + 26481, 26487, 26510, 26538, 26544, 26555, 26573, 26595, 26631, 26632, 26654, 26668, 26677, + 26682, 26690, 26707, 26710, 26743, 26773, 26790, 26794, 26888, 26978, 27008, 27047, 27053, + 27056, 27059, 27080, 27092, 27095, 27100, 27115, 27160, 27245, 27256, 27294, 27345, 27347, + 27350, 27384, 27433, 27440, 27571, 27606, 27627, 27646, 27735, 27792, 27805, 27826, 27852, + 27855, 27879, 27985, 28016, 28070, 28074, 28249, 28403, 28481, 28519, 28598, 28642, 28687, + 28904, 28929, 29047, 29278, 29344, 29449, 29625, 29902, 29969, 30008, 30020, 30021, 30040, + 30046, 30069, 30101, 30110, 30113, 30121, 30164, 30269, 30346, 30403, 30407, 30415, 30602, + 30617, 30864, 30878, 30952, 31002, 31003, 31004, 31044, 31133, 31302, 31326, 31335, 31337, + 31369, 31410, 31424, 31478, 31607, 31635, 31810, 32001, 32002, 32004, 32005, 32031, 32135, + 32162, 32277, 32292, 32395, 32542, 32586, 32667, 32823, 32998, 33010, 33161, 33335, 33486, + 33629, 33742, 34302, 34485, 35088, 35099, 35371, 35569, 35596, 35637, 35743, 35836, 35907, + 35909, 35936, 36001, 36100, 36225, 36385, 36535, 36695, 36847, 36907, 36969, 37007, 37549, + 37565, 37581, 37854, 37941, 38042, 38521, 38961, 39204, 39295, 39348, 39433, 39675, 39735, + 39812, 39906, 40005, 40008, 40011, 40016, 40017, 40033, 40249, 40288, 40450, 40807, 40863, + 41010, 41071, 41185, 41241, 41354, 41388, 41572, 41575, 41577, 41585, 41589, 41681, 41691, + 41742, 41895, 41920, 42040, 42468, 42882, 43063, 43145, 43209, 43234, 43380, 43463, 43965, + 44402, 44785, 44840, 44943, 44967, 44969, 45004, 45073, 45076, 45253, 45289, 45367, 45678, + 45691, 45780, 45850, 46006, 46143, 46148, 46165, 46237, 46249, 46258, 46430, 46455, 46651, + 46719, 46722, 46867, 46982, 47010, 47150, 47270, 47379, 47737, 48090, 48667, 48724, 48966, + 49092, 49130, 49352, 49616, 49857, 49930, 50007, 50010, 50011, 50020, 50047, 50173, 50187, + 50381, 50414, 50501, 50576, 50668, 50685, 50880, 51077, 51111, 51230, 51363, 51478, 51569, + 51720, 52061, 52263, 52358, 52463, 52490, 52627, 52837, 52870, 53374, 53441, 53820, 53849, + 54007, 54347, 54367, 54552, 54823, 54945, 55564, 55578, 56002, 56629, 56709, 56789, 57072, + 57173, 57493, 57793, 58253, 58504, 58537, 58569, 59466, 59519, 59529, 59572, 59610, 59621, + 59689, 59718, 60155, 60434, 60460, 60503, 60657, 60787, 61473, 61589, 61626, 61699, 61859, + 62096, 62321, 62492, 62722, 63110, 63142, 63554, 63923, 63947, 63988, 64084, 64630, 64699, + 64718, 64841, 65004, 65058, +];