Created
October 8, 2018 23:59
-
-
Save karlbright/1aaae4cb32db5ff2dbcdcfe170b10482 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use reqwest::{self, Error}; | |
pub fn get_gettorrent_data_for_url(url: &String) -> Result<String, Error> { | |
let body = reqwest::get(url)?.text()?; | |
Ok(body) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub mod http; | |
pub mod torrent; | |
pub mod url; | |
pub mod xml; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use base64; | |
use crypto::aes; | |
use crypto::blockmodes::PkcsPadding; | |
use crypto::buffer::{RefReadBuffer, RefWriteBuffer}; | |
// Decode response <torrent> | |
// binascii.unhexlify <checksum> | |
// if first 8 bytes are '\x01\x02\x03\x04\x11\x02e.' | |
// - START OF HEADING + START OF TEXT + END OF TEXT + END OF TRANSMISSION + DEVICE CONTROL 1 + START OF TEXT + e + . | |
// - md5 digest '%E0(tK8r]8KKU=crz!Vuex0b#I)H+!0n}%f0]L_x0ch++?-<#YHwXkvM6UL' | |
// - and use as key to aes decrypt 128 CBC with empty IV '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | |
// if first 4 bytes are '\x01\x02\x03\x04' | |
// - START OF HEADING + START OF TEXT + END OF TEXT + END OF TRANSMISSION | |
// - md5 digest 'tslive_key' | |
// - and use as key to aes decrypt 128 CBC with empty IV '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | |
// if first 4 bytes are '\x11\x02e.' | |
// - DEVICE CONTROL 1 + START OF TEXT + e + . | |
// - md5 digest '=Atl6GD#Vb+#QwW9zJy34lBOcM-7R7G)' | |
// - and use as key to aes decrypt 128 CBC with empty IV '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | |
// bencode decode result of above with ordered dict | |
pub fn decode_torrent_string_from_xml_response(torrent: &String) -> Vec<u8> { | |
let decoded = decode_base64_torrent_string(&torrent); | |
println!("{}", String::from_utf8_lossy(&decoded)); | |
let decrypted = decrypt_decoded_string(&decoded); | |
decrypted | |
} | |
fn decode_base64_torrent_string(torrent: &String) -> Vec<u8> { | |
base64::decode(torrent).unwrap() | |
} | |
fn decrypt_decoded_string(torrent: &Vec<u8>) -> Vec<u8> { | |
let key = "824e0bc114f58cdb5a49a0c0f142b424".as_bytes(); | |
let mut out = Vec::new(); | |
{ | |
let mut input = RefReadBuffer::new(&torrent); | |
let mut output = RefWriteBuffer::new(&mut out); | |
let mut decryptor = aes::cbc_decryptor( | |
aes::KeySize::KeySize128, | |
key, | |
b"00000000000000000000000000000000", | |
PkcsPadding, | |
); | |
decryptor | |
.decrypt(&mut input, &mut output, true) | |
.expect("Failed to decrypt"); | |
} | |
out | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use rand; | |
use rand::Rng; | |
use sha1::Sha1; | |
const REQUEST_SECRET: &str = "q\\\'X!;UL0J_<R*z#GBTL(9mCeRJbm/;L.oi9.`\\\"iETli9GD]`t&xlT(]MhJ{NVN,Q.)r~(6+9Bt(G,O%2c/g@sPi]<c[i\\\\ga]fkbHgwH:->ok4w8><y]^:Lw465+W4a(:"; | |
const TLDS: [&str; 3] = ["org", "info", "net"]; | |
pub fn get_gettorrent_url_for_pid(pid: &str) -> String { | |
let mut rng = rand::thread_rng(); | |
let host = get_hostname_for_gettorrent(&mut rng); | |
let path = get_path_for_gettorrent(); | |
let query = get_querystring_for_gettorrent(&pid, &mut rng); | |
format!("{}{}{}", host, path, query) | |
} | |
fn get_hostname_for_gettorrent<R: Rng>(rng: &mut R) -> String { | |
let server = rng.gen_range(1, 4); | |
let tld = TLDS[rng.gen_range(0, 3) as usize]; | |
format!("http://s{}.torrentstream.{}", server, tld) | |
} | |
fn get_path_for_gettorrent() -> &'static str { | |
"/gettorrent" | |
} | |
fn get_querystring_for_gettorrent<R: Rng>(pid: &str, rng: &mut R) -> String { | |
let num = rng.gen_range(1, <isize>::max_value()); | |
let querystring = format!("_n=3.1.16.1&_p=win32&_r={}&_v=3011601&pid={}", num, pid); | |
let signature = generate_signature_for_request(&querystring); | |
format!("?{}&_s={}", querystring, signature) | |
} | |
fn generate_signature_for_request(querystring: &String) -> String { | |
let mut hash = Sha1::new(); | |
let signature = querystring.replace("&", "#") + REQUEST_SECRET; | |
hash.update(signature.as_bytes()); | |
hash.digest().to_string() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use serde_xml_rs; | |
#[derive(Deserialize, Debug)] | |
pub struct XMLResponse { | |
#[serde(rename = "sig")] | |
pub signature: String, | |
pub torrent: String, | |
pub checksum: String, | |
} | |
pub fn parse_gettorrent_response_xml(xml: &String) -> XMLResponse { | |
serde_xml_rs::deserialize(xml.as_bytes()).unwrap() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment