Я написал этот код, который использует библиотеку nom для анализа некоторых значений из файла журнала, а затем выводит данные в формате JSON.
Мне пришлось использовать много переменных для случаев, когда синтаксический анализ ничего не нашел, потому что мне нужно было что-то вставить в json, даже если ничего не было, и если синтаксический анализатор ничего не нашел, код ломался, поэтому мне пришлось использовать много переменной, чтобы сделать так, чтобы, когда ничего не найдено, что-то отправлялось в JSON, например, для файла, в котором ничего нет, json выглядит так:
НО я привык ко многим переменным и код слишком сложен
окончательный json:
IP":" 197.164.254.1",
"Ports":" 22 ",
"vuln_details":"P2 - HIGH, Clear-Text Protocol - HTTP, http://192.168.254.60:80/, HTTP/1.1 200 OK\r\nP4 - LOW, Clickjacking HTTP, http://192.168.254.60:80/, \nP5 - INFO, CSP Not Enforced, http://192.168.254.60:80/, \nP5 - INFO, CSP Not Enforced, https://192.168.254.60:443/, \n",
"vuln_summary":{
"Critical":0,
"High":1,
"Info":2,
"Low":1,
"Medium":0,
"Score":8
}
}
],
"scan_date":"[2022-08-22](16:30)"
Используемый код:
use std::fs::File;
use std::io::prelude::*;
mod parser;
mod end_remover;
use parser::{untill_1, search_files};
use end_remover::{end_rmvr1, init_rmvr, init_rmvr3};
use serde_json::json;
use log::{debug, error, info, trace, warn};
use log4rs;
fn final_json(name:&str) {
// Reading data from log file
let mut file = File::open(name).expect("File not found");
let mut data = String::new();
file.read_to_string(&mut data).expect("Error while reading file");
//println!("{}", name);
//println!("{}", data);
// Parsing readed data
//PARSING SCAN DATE
// creating a variable with scan date only
let mut _date = "";
// checking if the parse works otherwise write a string
let parse_date = untill_1(&data, "92m[2");
if parse_date.is_err(){
_date = "No DATE Found";
log::warn!("No date was found");
} else {
log::info!("Date parsed succesfuly");
let parsed_date = parse_date.unwrap().0;
let parse_date2 = untill_1(parsed_date, "[0mx");
let parsed_date2 = parse_date2.unwrap().1;
// removing the initial and final characters
_date = init_rmvr3(end_rmvr1(parsed_date2));
//println!("{:?}", _date);
}
//PARSING IP
// creating a variable with only IP
let mut _ip = "";
// checking if the parse works otherwise write a string
let parse_ip = untill_1(&data, "Found,");
if parse_ip.is_err(){
_ip = "No IP Found";
} else {
let parse_ip = untill_1(&data, "Found,");
let parsed_ip = parse_ip.unwrap().0;
let parse_ip2 = untill_1(parsed_ip, "[92m");
let parsed_ip2 = parse_ip2.unwrap().1;
let parse_ip3 = untill_1(parsed_ip2, ",");
let ip_ports = parse_ip3.unwrap().0;
let parsed_ip_ports = init_rmvr(ip_ports);
let parse_ip4 = untill_1(parsed_ip_ports, ",");
let parsed_ip4 = parse_ip4.unwrap().1;
_ip = parsed_ip4;
}
//println!("\n {}", _ip);
//PARSING PORTS
// removing the initial comma
let mut _ports = "";
// checking if the parse works otherwise write a string
let parse_ports = untill_1(&data, "Found,");
if parse_ports.is_err(){
_ports = "No PORTS Found";
} else {
let parse_ports = untill_1(&data, "Found,");
let parsed_ports = parse_ports.unwrap().0;
let parse_ports2 = untill_1(parsed_ports, "[92m");
let parsed_ports2 = parse_ports2.unwrap().1;
let parse_ports3 = untill_1(parsed_ports2, ",");
let ip_ports = parse_ports3.unwrap().0;
let parsed_ip_ports = init_rmvr(ip_ports);
let parse_ports4 = untill_1(parsed_ip_ports, ",");
let parsed_ports4 = parse_ports4.unwrap().0;
_ports = end_rmvr1(end_rmvr1(init_rmvr(parsed_ports4)));
// replace whitespaces with ","
/*let whitespace_replacer = ports.replace(" ", ",");
// final ports
ports = &whitespace_replacer;*/
}
//println!("\n {}", _ports);
// VULN SUMMARY
// creating the variables with only the values in it
let mut _critical = "";
let mut _high = "";
let mut _medium = "";
let mut _low = "";
let mut _info = "";
let mut _score = "";
let mut _critical_value3 = 0;
let mut _high_value3 = 0;
let mut _medium_value3 = 0;
let mut _low_value3 = 0;
let mut _info_value3 = 0;
let mut _score_value3 = 0;
// checking if the parse works otherwise write a 0
let parse_critical = untill_1(&data, "Critical");
if parse_critical.is_err(){
_critical_value3 = 0;
_high_value3 = 0;
_medium_value3 = 0;
_low_value3 = 0;
_info_value3 = 0;
_score_value3 = 0;
} else {
// CRITICAL
// Parsing the log file to get every parameter in vuln summary
let parse_critical = untill_1(&data, "Critical");
let parsed_critical = parse_critical.unwrap().0;
let parse_high = untill_1(parsed_critical, "High");
let parse_high2 = untill_1(parsed_critical, "High");
// inserting in the variable
_critical = parse_high2.unwrap().1;
//
// HIGH
// creating a string with the rest of the file after High
let parsed_high = parse_high.unwrap().0;
let parse_medium = untill_1(parsed_high, "Medium");
let parse_medium2 = untill_1(parsed_high, "Medium");
// inserting in the variable
_high = parse_medium2.unwrap().1;
//
// MEDIUM
// creating a string with the rest of the file after Medium
let parsed_medium = parse_medium.unwrap().0;
let parse_low = untill_1(parsed_medium, "Low");
let parse_low2 = untill_1(parsed_medium, "Low");
// inserting in the variable
_medium = parse_low2.unwrap().1;
//
// LOW
// creating a string with the rest of the file after Low
let parsed_low = parse_low.unwrap().0;
let parse_info = untill_1(parsed_low, "Info");
let parse_info2 = untill_1(parsed_low, "Info");
// inserting in the variable
_low = parse_info2.unwrap().1;
//
// INFO
// creating a string with the rest of the file after Info
let parsed_info = parse_info.unwrap().0;
let parse_score = untill_1(parsed_info, "Score");
let parse_score2 = untill_1(parsed_info, "Score");
// inserting in the variable
_info = parse_score.unwrap().1;
//
// SCORE
let parsed_score = parse_score2.unwrap().0;
let parse_score3 = untill_1(parsed_score, "=");
// inserting in the variable
_score = parse_score3.unwrap().1;
//println!("{} {} {} {} {} {}", critical, high, medium, low, info, score);
}
//PARSE VULN DETAILS
//creating a variable with only details
let mut _details = "";
// checking if the parse works otherwise write a string
let parse_details = untill_1(&data, "Score");
if parse_details.is_err(){
_details = "No DETAILS Found"
} else {
let parsed_details = parse_details.unwrap().0;
let parse_details2 = untill_1(parsed_details, "P");
let parsed_details2 = parse_details2.unwrap().0;
let parse_details3 = untill_1(parsed_details2, "=");
let parsed_details3 = parse_details3.unwrap().1;
// final string with vuln details
_details = parsed_details3;
if _details == "PLETE! \u{1b}[0m\n\u{1b}[92m"{
_details = "No details";
} else {
_details = parsed_details3
}
//println!("\n {}", _details);
}
// JSON BUILDING
// extracting only the number for vuln_summary values and converting in integer at
.parse::<i32>().unwrap()
let mut ext_critical_value= "";
let mut critical_value:Vec<&str> = _critical.split_whitespace().collect();
let mut critical_value2 = critical_value.pop();
if critical_value2.is_none(){ext_critical_value = "0";} else {
ext_critical_value = critical_value2.unwrap();
}
let critical_value3 = ext_critical_value.parse::<i32>();
if critical_value3.is_err(){
_critical_value3 = 0;
} else {
_critical_value3 = critical_value3.unwrap();
}
//
let mut ext_high_value= "";
let mut high_value:Vec<&str> = _high.split_whitespace().collect();
let mut high_value2 = high_value.pop();
if high_value2.is_none(){ext_high_value = "0";} else {
ext_high_value = high_value2.unwrap();
}
let high_value3 = ext_high_value.parse::<i32>();
if high_value3.is_err(){
_high_value3 = 0;
} else {
_high_value3 = high_value3.unwrap();
}
//
let mut ext_medium_value= "";
let mut medium_value:Vec<&str> = _medium.split_whitespace().collect();
let mut medium_value2 = medium_value.pop();
if medium_value2.is_none(){ext_medium_value = "0";} else {
ext_medium_value = medium_value2.unwrap();
}
let medium_value3 = ext_medium_value.parse::<i32>();
if medium_value3.is_err(){
_medium_value3 = 0;
} else {
_medium_value3 = medium_value3.unwrap();
}
//
let mut ext_low_value= "";
let mut low_value:Vec<&str> = _low.split_whitespace().collect();
let mut low_value2 = low_value.pop();
if low_value2.is_none(){ext_low_value = "0";} else {
ext_low_value = low_value2.unwrap();
}
let low_value3 = ext_low_value.parse::<i32>();
if low_value3.is_err(){
_low_value3 = 0;
} else {
_low_value3 = low_value3.unwrap();
}
//
let mut ext_info_value= "";
let mut info_value:Vec<&str> = _info.split_whitespace().collect();
let mut info_value2 = info_value.pop();
if info_value2.is_none(){ext_info_value = "0";} else {
ext_info_value = info_value2.unwrap();
}
let info_value3 = ext_info_value.parse::<i32>();
if info_value3.is_err(){
_info_value3 = 0;
} else {
_info_value3 = info_value3.unwrap();
}
//
let mut ext_score_value= "";
let mut score_value:Vec<&str> = _score.split_whitespace().collect();
let mut score_value2 = score_value.pop();
if score_value2.is_none(){ext_score_value = "0";} else {
ext_score_value = score_value2.unwrap();
}
let score_value3 = ext_score_value.parse::<i32>();
if score_value3.is_err(){
_score_value3 = 0;
} else {
_score_value3 = score_value3.unwrap();
}
//
// covneritng in int
// creating json
let info_json = json!(
{
"scan_date":_date,
"hosts": [
{
"IP": _ip,
"Ports" : _ports,
"vuln_summary": {
"Critical": _critical_value3,
"High": _high_value3,
"Medium": _medium_value3,
"Low": _low_value3,
"Info": _info_value3,
"Score": _score_value3,
},
"vuln_details": _details,
},
],
}
);
println!("{}", name);
println!("{:?}", info_json);
info!("File {} parsed and sent succesfuly", name);
}
fn main() {
log4rs::init_file("src/logging_config.yaml", Default::default()).unwrap();
//FILE NAME READER
let res = search_files("output", "massvulnscan");
for filename in res {
let c_filename = String::from("output/");
let filename2 = c_filename + &filename.unwrap();
final_json(&filename2);
//println!("{}", filename.unwrap());
}
}
Функции until1 и search_file:
use nom::IResult;
use nom::bytes::complete::take_until;
extern crate nom;
use walkdir::WalkDir;
use std::ffi::OsString;
pub fn untill_1<'a>(s: &'a str, m: &'a str,) -> IResult<&'a str, &'a str>{
take_until(m)(s)
}
pub fn search_files<'a>(paths: &str, file_name: &str) -> Vec<Result<String, OsString>> {
let mut result = Vec::new();
for file in WalkDir::new(paths).into_iter().filter_map(|file| file.ok()) {
if file.metadata().unwrap().is_file() &&
file.file_name().to_str().unwrap().contains(file_name) {
let str_new = file.file_name().to_os_string();
//println!("{}", str_new.unwrap());
result.push(str_new.into_string());
}
}
return result;
}
Функции init_rmvr и end_rmvr:
pub fn init_rmvr(value: &str) -> &str {
let mut chars = value.chars();
chars.next();
chars.as_str()
}
pub fn end_rmvr1(value: &str) -> &str {
let mut chars = value.chars();
chars.next_back();
chars.as_str()
}
pub fn init_rmvr3(value: &str) -> &str {
let mut chars = value.chars();
chars.next();
chars.next();
chars.next();
chars.as_str()
}
ПРОБЛЕМА В том, что файл журнала может быть таким
Starting PostgreSQL 13 database server: main.
[94m[*][0m Loaded configuration file from /usr/share/sniper/sniper.conf [94m[[0m[92mOK[0m[94m][0m
[94m[*][0m Loaded configuration file from /root/.sniper.conf [94m[[0m[92mOK[0m[94m][0m
[94m[*][0m Saving loot to /usr/share/sniper/loot/workspace/nosva [94m[[0m[92mOK[0m[94m][0m
[94m[*][0m Scanning 192.158.1.38 [94m[[0m[92mOK[0m[94m][0m
[91m ____ [0m
[91m _________ / _/___ ___ _____[0m
[91m / ___/ __ \ / // __ \/ _ \/ ___/[0m
[91m (__ ) / / // // /_/ / __/ / [0m
[91m /____/_/ /_/___/ .___/\___/_/ [0m
[91m /_/ [0m
[93m + -- --=[ https://sn1persecurity.com[0m
[93m + -- --=[ Sn1per v9.0 by @xer0dayz[0m
[92m====================================================================================[0m•x[92m[2022-08-22](15:56)[0mx•
[91m RUNNING SC0PE WEB VULNERABILITY SCAN [0m
[92m====================================================================================[0m•x[92m[2022-08-22](15:56)[0mx•
P5 - INFO, CSP Not Enforced, http://192.158.1.38/,
P2 - HIGH, Clear-Text Protocol - HTTP, http://192.158.1.38/, HTTP/1.1 200 OK
P4 - LOW, Clickjacking HTTP, http://192.158.1.38/,
P5 - INFO, CSP Not Enforced, https://192.158.1.38:443/,
[92m====================================================================================[0m•x[92m[2022-08-22](15:56)[0mx•
[91m RUNNING SC0PE NETWORK VULNERABILITY SCAN [0m
[92m====================================================================================[0m•x[92m[2022-08-22](15:56)[0mx•
P5 - INFO, Interesting Ports Found, 192.158.1.38, 21 8080 9090 7070
[92m====================================================================================[0
m•x[92m[2022-08-22](15:56)[0mx•
====================================================================================
•?((¯°·..• Sc0pe Vulnerability Report by @xer0dayz •._.·°¯))؟•
====================================================================================
Critical: 0
High: 1
Medium: 0
Low: 1
Info: 2
Score: 8
====================================================================================
P2 - HIGH, Clear-Text Protocol - HTTP, http://192.158.1.38:80/, HTTP/1.1 200 OK
P4 - LOW, Clickjacking HTTP, http://192.158.1.38:80/,
P5 - INFO, CSP Not Enforced, http://192.158.1.38:80/,
P5 - INFO, CSP Not Enforced, https://192.158.1.38:443/,
====================================================================================
[92m====================================================================================[0m•x[92m[2022-08-22](15:56)[0mx•
[91m SCAN COMPLETE! [0m
[92m====================================================================================[0m•x[92m[2022-08-22](15:56)[0mx•
Но может быть и ЭТО
Starting PostgreSQL 13 database server: main.
[94m[*][0m Loaded configuration file from /usr/share/sniper/sniper.conf [94m[[0m[92mOK[0m[94m][0m
[94m[*][0m Loaded configuration file from /root/.sniper.conf [94m[[0m[92mOK[0m[94m][0m
[94m[*][0m Saving loot to /usr/share/sniper/loot/workspace/nosva [94m[[0m[92mOK[0m[94m][0m
[94m[*][0m Scanning 197.164.254.1 [94m[[0m[92mOK[0m[94m][0m
[91m ____ [0m
[91m _________ / _/___ ___ _____[0m
[91m / ___/ __ \ / // __ \/ _ \/ ___/[0m
[91m (__ ) / / // // /_/ / __/ / [0m
[91m /____/_/ /_/___/ .___/\___/_/ [0m
[91m /_/ [0m
[93m + -- --=[ https://sn1persecurity.com[0m
[93m + -- --=[ Sn1per v9.0 by @xer0dayz[0m
[92m====================================================================================[0m•x[92m[2022-09-19](14:52)[0mx•
[91m RUNNING SC0PE WEB VULNERABILITY SCAN [0m
[92m====================================================================================[0m•x[92m[2022-09-19](14:52)[0mx•
поэтому мне пришлось использовать много переменных для случаев, когда синтаксический анализ ничего не нашел, потому что мне нужно было что-то поместить в json, даже если ничего не было, и если синтаксический анализатор ничего не нашел, код сломался, поэтому мне пришлось использовать много переменных, чтобы сделать так, чтобы, когда ничего не было найдено, что-то отправлялось в json, например, для файла, в котором ничего не было, json il вроде этого:
{
"hosts":[
{
"IP":"No IP Found",
"Ports":"No PORTS Found",
"vuln_details":"No DETAILS Found",
"vuln_summary":{
"Critical":0,
"High":0,
"Info":0,
"Low":0,
"Medium":0,
"Score":0
}
}
],
"scan_date":"[2022-09-19](14:52)"
}
НО я привык ко многим переменным, а код слишком сложный, кто-нибудь может мне помочь? Большое тебе спасибо.
Эрти Десу