Skip to content

Commit

Permalink
minor changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Asjidkalam committed Aug 1, 2021
1 parent 99e8c69 commit be84b35
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 18 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name = "ruo"
version = "0.1.0"
edition = "2018"
authors = ["Asjid Kalam <asjid@odinshell.ninja>"]
description = "Tiny hash cracked written in rust."
repository = "https://github.com/Asjidkalam/ruo.git"
license = "MIT"

[dependencies]
instant = "0.1.9"
Expand Down
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# `Ruo` 🧁
Ruo is a dictionary-based password cracker written in rust 🦀. The primary purpose is to crack weak hashes/commonly used passwords.

Cracked passwords will be printed to the terminal and saved in the file `$HOME/hashes.saved`. The `$HOME/hashes.saved` file is also used to not load password hashes that you already cracked when you run ruo the next time.

<p align="left">
<img src="https://img.shields.io/badge/version-0.1.0-blue.svg" title="version" alt="version">
</p>


## Available algorithms


| Name | Algorithm | Crates.io |
|-------------|------------|-----------|
| `md5` | MD5 | [![crates.io](https://img.shields.io/crates/v/md5.svg)](https://crates.io/crates/md5) |
| `sha1` | SHA-1 | [![crates.io](https://img.shields.io/crates/v/sha1.svg)](https://crates.io/crates/sha-1) |
| `sha256` | SHA-2 256 | [![crates.io](https://img.shields.io/crates/v/sha256.svg)](https://crates.io/crates/sha2) |
| `sha512` | SHA-2 512 | [![crates.io](https://img.shields.io/crates/v/sha256.svg)](https://crates.io/crates/sha2) |
|`ripemd320` | RIPEMD320 | [![crates.io](https://img.shields.io/crates/v/ripemd320.svg)](https://crates.io/crates/ripemd320)|


## Build From Source

### Prerequisites

You'll need the following tools to build from source:

* [Rust](https://www.rust-lang.org/en-US/install.html)
* `Cargo`


### Building

Clone the repository and use cargo to generate a release build.
```sh
$ git clone https://github.com/Asjidkalam/ruo.git
$ cd ruo/
$ cargo build --release
```

## Usage
```sh
$ ./target/release/ruo <WORDLIST-FILE-PATH> <HASH-TO-CRACK>
```

### Example
```
🔫 ruo v0.1
Loaded SHA-256 hash.
Loaded the wordlist file in 1838 millisecs.
🤍 Cracked! 244f28ce3685167745ad3a7f1760fd4483bbbb3fd150b9087b95442d4d6fd905 -> "PASSWORD1" in 6 millisecs
```

## Contribute

* Suggest a feature / Report a bug
* More algorithms
* Better optimization
* Help me document the code :)

## License
This project is licensed under the terms of the MIT license.
Check the [LICENSE](LICENSE.md) file out for license rights and limitations.

🍰
2 changes: 1 addition & 1 deletion src/banner.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub fn display_banner() {
println!("ruo (debug build)");
println!("🔫 ruo v0.1");
}
56 changes: 39 additions & 17 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use std::env;
use std::fs;
use std::io::prelude::*;
use std::io::ErrorKind;
use std::path::Path;
use std::process;
Expand All @@ -19,8 +20,10 @@ lazy_static! {

/*
ruo currently supports: MD5, SHA1, RipeMD320, SHA256 and SHA512
@odinshell - 01/08/2021
*/

// debug
static mut LOAD_TIME: u128 = 0;

#[derive(Serialize, Deserialize)]
Expand All @@ -29,10 +32,25 @@ struct LocalHash {
plaintext: String,
}

fn load_local_hive() -> Vec<LocalHash> {
let json_file_path = Path::new(&*LOCAL_HASH_PATH);

let data = fs::read_to_string(json_file_path).unwrap();
let mut local_hive: Vec<LocalHash> = Vec::new();
if fs::metadata(json_file_path).unwrap().len() != 0 {
local_hive = serde_json::from_str(&data).unwrap();
}
local_hive
}

fn crack(line: String, hash_len: usize, now: std::time::Instant) {
let formatted_hash: String = algorithms::create_hash(&line, hash_len);

if formatted_hash == *HASH_INPUT {
/*
LOAD_TIME and unsafe{} is currently used for wordlist load time debug
will be removed later.
*/
unsafe {
println!(
"🤍 Cracked! {} -> \"{}\" in {} millisecs",
Expand All @@ -42,16 +60,26 @@ fn crack(line: String, hash_len: usize, now: std::time::Instant) {
);
}

// save the hash locally
let mut local_hive: Vec<LocalHash> = Vec::new();
// loading the hash file, adding the new hash and saving locally.
let mut local_hive = load_local_hive();

let new_hash = LocalHash {
hash: formatted_hash,
plaintext: line,
};

local_hive.push(new_hash);
let json = serde_json::to_string(&local_hive).unwrap();

fs::write(&*LOCAL_HASH_PATH, &json).expect("Unable to write locally.");
let mut file_write = fs::OpenOptions::new()
.write(true)
.append(false)
.open(&*LOCAL_HASH_PATH)
.unwrap();

if let Err(e) = writeln!(file_write, "{}", &json) {
eprintln!("Couldn't write to file: {}", e);
}

process::exit(0);
}
Expand All @@ -62,15 +90,13 @@ fn main() -> std::io::Result<()> {

let mut hash_dict: Vec<String> = vec![];

// TODO: use a real fucking argument parser.
// TODO: argument parser lol.
let args: Vec<String> = env::args().collect();
let wordlist_file = &args[1];

// println!("📋 Wordlist: {}", wordlist_file);

// check for saved hashes locally
// BUGS: file is overwriting, not appending.
// TODO: read the entire local file to memory before writing.
fs::create_dir_all(format!("{}/.ruo", env::home_dir().unwrap().display()))?;

let f = fs::File::open(&*LOCAL_HASH_PATH);
let _ = match f {
Ok(file) => file,
Expand All @@ -83,22 +109,16 @@ fn main() -> std::io::Result<()> {
},
};

let json_file_path = Path::new(&*LOCAL_HASH_PATH);

let data = fs::read_to_string(json_file_path).unwrap();

let mut local_hive: Vec<LocalHash> = Vec::new();
if fs::metadata(json_file_path).unwrap().len() != 0 {
local_hive = serde_json::from_str(&data)?;
}
let local_hive = load_local_hive();

// check if the current hash matches to the hash in the local_hive.
for hash_object in local_hive {
// check if the current hash matches to the hash in the local_hive.
if hash_object.hash == *HASH_INPUT {
println!(
"🤍 Saved hash found! {} -> \"{}\"",
hash_object.hash, hash_object.plaintext
);
process::exit(0);
}
}

Expand Down Expand Up @@ -144,11 +164,13 @@ fn main() -> std::io::Result<()> {
hash_dict.push(line?.trim_end().to_string());
}

// debug
unsafe {
LOAD_TIME = now.elapsed().as_millis();
println!("loaded the wordlist file in {} millisecs.", LOAD_TIME);
}

// rayon goes brr
hash_dict.par_iter().for_each(|lines| {
let line = lines.clone();
crack(line, hash_len, now);
Expand Down

0 comments on commit be84b35

Please sign in to comment.