Download src/vm/executor.rs from sanbo1200/ct: direct link, hf CLI and curl.
- Browser
- Download file 6.1 kB
-
https://huggingface.co/spaces/sanbo1200/ct/resolve/main/src/vm/executor.rs
- Command line
-
hf download hf://spaces/sanbo1200/ct/src/vm/executor.rs
-
curl -L -o executor.rs https://huggingface.co/spaces/sanbo1200/ct/resolve/main/src/vm/executor.rs
6.1 kB
| // JavaScript VM executor for ChatGPT reverse engineering | |
| use crate::utils::{Result, Utils}; | |
| use crate::vm::{Decompiler, Parser}; | |
| use base64::{Engine as _, engine::general_purpose}; | |
| use rand::Rng; | |
| use serde_json::{Map, Value}; | |
| use std::collections::HashMap; | |
| /// Virtual Machine for executing turnstile challenges | |
| pub struct VM; | |
| impl VM { | |
| /// HTML object used in VM calculations | |
| const HTML_OBJECT: &'static str = r#"{"x":0,"y":1219,"width":37.8125,"height":30,"top":1219,"right":37.8125,"bottom":1249,"left":0}"#; | |
| /// Generate turnstile token (simplified) | |
| pub fn get_turnstile(_bytecode: &str, _token: &str, _ip_info: &str) -> Result<String> { | |
| // Placeholder implementation: real logic would parse bytecode and token to | |
| // compute the turnstile token. For now, keep a deterministic shape so the | |
| // rest of the pipeline can execute. | |
| Ok(format!( | |
| "0.{}.{}", | |
| chrono::Utc::now().timestamp(), | |
| rand::random::<u32>() | |
| )) | |
| } | |
| /// Decompile VM bytecode to JavaScript | |
| pub fn decompile_vm(turnstile: &str, token: &str) -> Result<String> { | |
| Decompiler::decompile_vm(turnstile, token) | |
| } | |
| /// Parse keys from decompiled JavaScript | |
| pub fn parse_keys(decompiled_code: &str) -> Result<(String, HashMap<String, String>)> { | |
| Parser::parse_keys(decompiled_code) | |
| } | |
| /// Execute JavaScript code and extract result | |
| /// | |
| /// Note: This is a simplified stub. Full implementation would require | |
| /// a JavaScript engine like V8 or QuickJS bindings | |
| pub fn execute_js(_code: &str) -> Result<String> { | |
| // In a full implementation, this would: | |
| // 1. Create a JavaScript context | |
| // 2. Execute the decompiled code | |
| // 3. Extract the result | |
| // For now, return a placeholder | |
| Ok("{}".to_string()) | |
| } | |
| /// XOR two strings | |
| pub fn xor(data: &str, key: &str) -> String { | |
| Utils::xor_strings(data, key) | |
| } | |
| /// Add values to VM payload based on extracted operations | |
| pub fn add_vm_values( | |
| payload: &mut Map<String, Value>, | |
| xor_key: &str, | |
| ip_info: &str, | |
| ) -> Result<()> { | |
| let mut rng = rand::rng(); | |
| // Random values | |
| let random1: f64 = rng.random(); | |
| let random2: f64 = rng.random(); | |
| payload.insert( | |
| "19.33".to_string(), | |
| Value::String( | |
| general_purpose::STANDARD | |
| .encode(Self::xor(&format!("{}", random1 + 0.6), xor_key).as_bytes()), | |
| ), | |
| ); | |
| payload.insert( | |
| "56.04".to_string(), | |
| Value::String( | |
| general_purpose::STANDARD | |
| .encode(Self::xor(r#"["Google Inc.","Win32",8,0]"#, xor_key).as_bytes()), | |
| ), | |
| ); | |
| payload.insert( | |
| "14.85".to_string(), | |
| Value::String( | |
| general_purpose::STANDARD.encode(Self::xor(Self::HTML_OBJECT, xor_key).as_bytes()), | |
| ), | |
| ); | |
| payload.insert( | |
| "31.17".to_string(), | |
| Value::String(general_purpose::STANDARD.encode( | |
| Self::xor("oai/apps/hasDismissedTeamsNoAuthUpsell,oai-did", xor_key).as_bytes(), | |
| )), | |
| ); | |
| payload.insert( | |
| "7.1".to_string(), | |
| Value::String( | |
| general_purpose::STANDARD | |
| .encode(Self::xor(&rng.random_range(1..5).to_string(), xor_key).as_bytes()), | |
| ), | |
| ); | |
| payload.insert( | |
| "75.89".to_string(), | |
| Value::String(general_purpose::STANDARD.encode(Self::xor(ip_info, xor_key).as_bytes())), | |
| ); | |
| payload.insert( | |
| "84.91".to_string(), | |
| Value::String( | |
| general_purpose::STANDARD | |
| .encode(Self::xor("https://chatgpt.com/", xor_key).as_bytes()), | |
| ), | |
| ); | |
| payload.insert( | |
| "30.7".to_string(), | |
| Value::String( | |
| general_purpose::STANDARD | |
| .encode(Self::xor(&random1.to_string(), &random1.to_string()).as_bytes()), | |
| ), | |
| ); | |
| payload.insert( | |
| "27.36".to_string(), | |
| Value::Number(serde_json::Number::from_f64(random2).unwrap()), | |
| ); | |
| Ok(()) | |
| } | |
| /// Simplified bytecode decompiler (placeholder for complex implementation) | |
| pub fn decompile_bytecode(_bytecode: &str) -> Result<HashMap<String, String>> { | |
| // This is a placeholder for the complex JavaScript decompiler | |
| // In the real implementation, this would parse and execute the bytecode | |
| let mut operations = HashMap::new(); | |
| // These would be extracted from the actual bytecode | |
| operations.insert("xor_key".to_string(), "48.51".to_string()); | |
| operations.insert("19.33".to_string(), "random_add".to_string()); | |
| operations.insert("56.04".to_string(), "vendor".to_string()); | |
| operations.insert("14.85".to_string(), "element".to_string()); | |
| operations.insert("31.17".to_string(), "localstorage".to_string()); | |
| operations.insert("7.1".to_string(), "history".to_string()); | |
| operations.insert("75.89".to_string(), "ipinfo".to_string()); | |
| operations.insert("84.91".to_string(), "location".to_string()); | |
| operations.insert("30.7".to_string(), "random_1".to_string()); | |
| operations.insert("27.36".to_string(), "random_2".to_string()); | |
| Ok(operations) | |
| } | |
| /// Process and execute VM bytecode with full pipeline | |
| pub fn process_bytecode( | |
| turnstile: &str, | |
| token: &str, | |
| ip_info: &str, | |
| ) -> Result<Map<String, Value>> { | |
| // Step 1: Decompile bytecode | |
| let decompiled = Self::decompile_vm(turnstile, token)?; | |
| // Step 2: Parse keys from decompiled code | |
| let (xor_key, _parsed_keys) = Self::parse_keys(&decompiled)?; | |
| // Step 3: Build payload | |
| let mut payload = Map::new(); | |
| Self::add_vm_values(&mut payload, &xor_key, ip_info)?; | |
| Ok(payload) | |
| } | |
| } | |