From 086b51d48d8fc459f5e91b36168a34fbf289fd72 Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Tue, 10 Nov 2020 23:16:51 +0100 Subject: [PATCH] init --- .gitignore | 5 ++++ Cargo.toml | 4 ++++ rustfmt.toml | 12 ++++++++++ tokencracker/Cargo.toml | 20 ++++++++++++++++ tokencracker/src/api.rs | 42 +++++++++++++++++++++++++++++++++ tokencracker/src/lib.rs | 6 +++++ tokencracker/src/main.rs | 50 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 139 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 rustfmt.toml create mode 100644 tokencracker/Cargo.toml create mode 100644 tokencracker/src/api.rs create mode 100644 tokencracker/src/lib.rs create mode 100644 tokencracker/src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73c5b53 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/target +.idea +*.lock +*.iml +.vscode diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..73383c9 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,4 @@ +[workspace] +members = [ + "tokencracker", +] diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..1059111 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,12 @@ +unstable_features = true +binop_separator = "Back" +format_code_in_doc_comments = true +format_macro_matchers = true +format_strings = true +imports_layout = "HorizontalVertical" +match_block_trailing_comma = true +merge_imports = true +normalize_comments = true +use_field_init_shorthand = true +use_try_shorthand = true +wrap_comments = true diff --git a/tokencracker/Cargo.toml b/tokencracker/Cargo.toml new file mode 100644 index 0000000..27d46fe --- /dev/null +++ b/tokencracker/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "tokencracker" +version = "0.1.0" +authors = ["LordMZTE "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[[bin]] +name = "jmtoken" +path = "src/main.rs" + +[dependencies] +anyhow = "1.0.34" +clap = "2.33.3" +md5 = "0.7.0" +reqwest = "0.10.8" +serde = { version = "1.0.117", features = ["derive"] } +serde_json = "1.0.59" +tokio = { version = "~0.2", features = ["full"] } diff --git a/tokencracker/src/api.rs b/tokencracker/src/api.rs new file mode 100644 index 0000000..241ad23 --- /dev/null +++ b/tokencracker/src/api.rs @@ -0,0 +1,42 @@ +use serde::de::{Error, Unexpected, Visitor}; +use core::fmt::Formatter; +use serde::{Deserialize, Deserializer}; +#[derive(Deserialize, Debug)] +pub struct UserResponse { + pub status: u16, + pub user: JensmemesUser, +} + +#[derive(Deserialize, Debug)] +pub struct JensmemesUser { + pub name: String, + pub tokenhash: String, + pub userdir: String, + pub id: String, + #[serde(deserialize_with = "deserialize_uploads")] + pub dayuploads: u32, +} + +fn deserialize_uploads<'de, D>(de: D) -> Result +where + D: Deserializer<'de>, +{ + struct Vis; + + impl<'de> Visitor<'de> for Vis { + type Value = u32; + + fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { + write!(fmt, "a u32") + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + v.parse().map_err(|_| E::invalid_type(Unexpected::Str(v), &"a u32")) + } + } + + de.deserialize_str(Vis) +} diff --git a/tokencracker/src/lib.rs b/tokencracker/src/lib.rs new file mode 100644 index 0000000..42f0922 --- /dev/null +++ b/tokencracker/src/lib.rs @@ -0,0 +1,6 @@ +pub mod api; + +/// returns the md5 hash of the input string formatted as hex +pub fn hex_string_hash(s: &str) -> String { + format!("{:x}", md5::compute(s.as_bytes())) +} diff --git a/tokencracker/src/main.rs b/tokencracker/src/main.rs new file mode 100644 index 0000000..1d57440 --- /dev/null +++ b/tokencracker/src/main.rs @@ -0,0 +1,50 @@ +use anyhow::Result; +use clap::{App, Arg}; +use reqwest::{Client, Url}; +use tokencracker::{api::UserResponse, hex_string_hash}; + +#[tokio::main] +async fn main() -> Result<()> { + let http = Client::builder().build()?; + + let matches = App::new("tokencracker") + .arg( + Arg::with_name("discord_id") + .index(1) + .required(true) + .help("The discord ID of the user whos token to crack."), + ) + .get_matches(); + + let id = matches.value_of("discord_id").unwrap(); + + // yes, this is the actual jensmemes token algorythm + let private = hex_string_hash(id); + let public = hex_string_hash(&private); + + // get discord username from jensmemes API + let response = http + .get(Url::parse_with_params( + "https://data.tilera.xyz/api/jensmemes/user", + &[("id", &public)], + )?) + .send() + .await?; + + let username = + if let (200..=210, Ok(usr)) = (response.status().as_u16(), response.bytes().await) { + let UserResponse { user, .. } = serde_json::from_slice::(&usr)?; + user.name + } else { + "Not in Database".into() + }; + + println!( + "Username: {} +Public Token: {} +Private Token: {}", + username, public, private + ); + + Ok(()) +}