• XSS.stack #1 – первый литературный журнал от юзеров форума

софт для парсинга логов со стиллера

В sql пойдёт? Потом сделаешь себе выборку
C++:
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), не реклама, но продукт хороший.
Можно настроить фильтры по домену запроса, формату логина (емейл или телефон), формат пароля, фильтры от совпадений, очистки от лишнего и т.д.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх