подскажите пожалуйста чем можно парсить?
вытаскивать только нужные мне сервисы
спасибо
вытаскивать только нужные мне сервисы
спасибо
use crc32fast;
use thousands::Separable;
use walkdir::WalkDir;
use zip;
fn main() {
let mut clear = false;
let mut database: String = String::from("base.db");
let mut dirs: Vec<String> = Vec::new();
let pargs = std::env::args().skip(1);
for arg in pargs {
if arg.contains("-clear") || arg.contains("--clear") {
clear = true;
} else if arg.contains("-db") || arg.contains("--db") {
let d: Vec<&str> = arg.split(" ").collect();
database = d[1].to_string();
} else {
let meta = std::fs::metadata(&arg).unwrap();
if meta.is_dir() {
dirs.push(arg);
}
}
}
let mut db = rusqlite::Connection::open(&database).unwrap();
db.execute("create table if not exists logs (id int, host string, login string, password string, unique(host,login,password))",[]).unwrap();
let rows_count1: i32 = db
.query_row("SELECT MAX(_ROWID_) FROM 'logs' LIMIT 1;", [], |row| {
row.get(0)
})
.unwrap_or(0);
let tx = db.transaction().unwrap();
for dir in &dirs {
for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) {
if entry.path().is_file() {
let ilename = &entry.path().file_name().unwrap();
let filename = match ilename.to_str() {
Some(f) => f,
None => continue,
};
if (filename.contains("redential") || filename.contains("assword"))
&& filename.ends_with("txt")
{
let data = match std::fs::read_to_string(&entry.path()) {
Ok(data) => data,
Err(err) => {
println!("[{}]: {}", &entry.path().display(), err);
continue;
}
};
collect_passwords(data, &tx);
} else if filename.ends_with("zip") {
let reader = match std::fs::OpenOptions::new().read(true).open(&entry.path()) {
Ok(reader) => reader,
Err(e) => panic!("[68] {} -> {}", &entry.path().display(), e),
};
let mut z_file = match zip::ZipArchive::new(reader) {
Ok(z) => z,
Err(_) => continue,
};
for i in 0..z_file.len() {
let mut file = match z_file.by_index(i) {
Ok(f) => f,
Err(_) => continue,
};
if file.is_file()
&& (file.name().contains("assword")
|| file.name().contains("Credential"))
&& file.name().ends_with("txt")
{
let mut data: Vec<u8> = Vec::new();
let _ = match std::io::copy(&mut file, &mut data) {
Ok(_) => {}
Err(err) => {
println!("{}", err);
continue;
}
};
let data = match std::str::from_utf8_mut(&mut data) {
Ok(data) => data,
Err(_) => continue,
};
collect_passwords(data.to_string(), &tx);
}
}
}
}
}
}
tx.commit().unwrap();
if clear {
for dir in dirs {
for entry in std::fs::read_dir(&dir).unwrap() {
if entry.as_ref().unwrap().path().is_dir() {
std::fs::remove_dir_all(entry.unwrap().path()).unwrap();
} else {
std::fs::remove_file(&entry.unwrap().path()).unwrap();
}
}
}
}
let rows_count2: i32 = db
.query_row("SELECT MAX(_ROWID_) FROM 'logs' LIMIT 1;", [], |row| {
row.get(0)
})
.unwrap();
println!(
"rows added: {}",
(rows_count2 - rows_count1).separate_with_commas()
);
println!("total rows: {}", rows_count2.separate_with_commas());
// Ok(())
}
fn collect_passwords(data: String, tx: &rusqlite::Transaction) {
let hash = crc32fast::hash(data.as_bytes());
let mut buf = String::new();
let delim = if data.contains("\r\n") { "\r\n" } else { "\n" };
let lines: Vec<&str> = data.split(delim).collect();
for line in lines {
if line.starts_with("URL")
|| line.starts_with("Url")
|| line.starts_with("HOST")
|| line.starts_with("Host")
|| line.starts_with("Server")
{
let line = line
.replace("URL:", "")
.replace("Url:", "")
.replace("Server:", "")
.replace("HOST:", "")
.replace("Hostname:", "")
.replace("Host:", "")
.replace(" ", "")
.replace("\t", "");
buf.push_str(&line);
buf.push_str("|");
}
if line.starts_with("Username") || line.starts_with("USER") || line.starts_with("Login") {
let u: Vec<&str> = line.split(":").collect();
if u.len() != 2 {
continue;
}
let username = u[1].replace(" ", "").replace("\t", "").to_lowercase();
buf.push_str(&username);
buf.push_str("|");
}
if line.starts_with("Password") || line.starts_with("PASS") {
let p: Vec<&str> = line.split(":").collect();
if p.len() != 2 {
continue;
}
let password = p[1].replace(" ", "").replace("\t", "");
buf.push_str(&password);
buf.push_str("\n");
}
}
let mut creds: Vec<&str> = buf.split("\n").collect();
creds.dedup();
creds.pop();
for i in creds {
let val = i.split("|").collect::<Vec<&str>>();
if val.len() != 3 {
continue;
}
let res = tx.execute(
"insert or ignore into logs (id,host,login,password) values(?1,?2,?3,?4)",
rusqlite::params![&hash, val[0], val[1], val[2]],
);
match res {
Ok(_) => {}
Err(e) => panic!("{}", e),
};
}
}
CrystalSorter используй (от создателей DCRAT), не реклама, но продукт хороший.подскажите пожалуйста чем можно парсить?
вытаскивать только нужные мне сервисы
спасибо