From e344defb3b63e4b0bdd59b511172f3948916918a Mon Sep 17 00:00:00 2001 From: caret Date: Sun, 11 Feb 2024 13:16:55 -0600 Subject: [PATCH] so close --- .gitignore | 1 + src/routes/game_routes.rs | 55 ++++++++++++++++++++++++++++++++++++--- utils/README.md | 13 ++++++--- utils/pad_plaintext.py | 15 +++++++++++ 4 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 utils/pad_plaintext.py diff --git a/.gitignore b/.gitignore index 69db9d3..a95b555 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target Cargo.lock *.exe +*.pcapng diff --git a/src/routes/game_routes.rs b/src/routes/game_routes.rs index d301df2..148205d 100644 --- a/src/routes/game_routes.rs +++ b/src/routes/game_routes.rs @@ -10,6 +10,11 @@ macro_rules! resp { }; } +pub fn encresp(content: &str) -> HttpResponse { + let encrypted_content = aes_en(&content); // Encrypt the content. + resp!(encrypted_content) // Use your macro here, if it can be adapted to work with Vec +} + /////////////////////////////////////////////////////////////////////////////////////////// use serde::Deserialize; @@ -45,6 +50,9 @@ fn clean_json_string(input: &str) -> String { .collect(); cleaned_str } + +// {'result':200,'encresponse':{}} + #[post("/game")] pub async fn game_stuff(body: web::Bytes, req: actix_web::HttpRequest) -> HttpResponse { // For getting the game online, we need to give it a json type encrypted! @@ -61,14 +69,53 @@ pub async fn game_stuff(body: web::Bytes, req: actix_web::HttpRequest) -> HttpRe Ok(data) => { // You can now work with the deserialized data println!("{}",format!("data.protocol -> {}", data.protocol).black().bold().on_magenta()); - // Respond with success or any other logic you need - return resp!(""); + match data.protocol.as_str() { + "unlock" => return encresp("{'result':200,'response':{}}"), // 1st + "gameconfig" => return encresp("{'result':400,'response':{}}"), // 2nd -> not getting the right data??? + "information" => return encresp("{'result':400,'response':{}}"), // 3rd + "ranking" => return encresp("{'result':200,'response':{}}"), // 4th + "auth" => return encresp("{'result':200,'response':{}}"), + "achievement" => return encresp("{'result':200,'response':{}}"), + "achievementyell" => return encresp("{'result':200,'response':{}}"), + "checkword" => return encresp("{'result':200,'response':{}}"), + "discard" => return encresp("{'result':200,'response':{}}"), + "gacha.member" => return encresp("{'result':200,'response':{}}"), + "gameentry" => return encresp("{'result':200,'response':{}}"), + "gameentry.center" => return encresp("{'result':200,'response':{}}"), + "gameresult" => return encresp("{'result':200,'response':{}}"), + "gametotalresult" => return encresp("{'result':200,'response':{}}"), + "gameexit" => return encresp("{'result':200,'response':{}}"), + "getmembercard" => return encresp("{'result':200,'response':{}}"), + "music.unlock" => return encresp("{'result':200,'response':{}}"), + "present" => return encresp("{'result':200,'response':{}}"), + "printcard" => return encresp("{'result':200,'response':{}}"), + "profile.inquiry" => return encresp("{'result':200,'response':{}}"), + "profile.print" => return encresp("{'result':200,'response':{}}"), + "userranking" => return encresp("{'result':200,'response':{}}"), + "registerafter" => return encresp("{'result':200,'response':{}}"), + "scfescheck" => return encresp("{'result':200,'response':{}}"), + "scfesregister" => return encresp("{'result':200,'response':{}}"), + "sellcard" => return encresp("{'result':200,'response':{}}"), + "setterminallog" => return encresp("{'result':200,'response':{}}"), + "setterminalstatus" => return encresp("{'result':200,'response':{}}"), + "travelstamp" => return encresp("{'result':200,'response':{}}"), + "TravelStart" => return encresp("{'result':200,'response':{}}"), + "TravelResult" => return encresp("{'result':200,'response':{}}"), + "TravelSnap.commit" => return encresp("{'result':200,'response':{}}"), + "TravelSnap.inquiry" => return encresp("{'result':200,'response':{}}"), + "TravelSnap.share" => return encresp("{'result':200,'response':{}}"), + "TravelSnap.print" => return encresp("{'result':200,'response':{}}"), + "userdata.get" => return encresp("{'result':200,'response':{}}"), + "userdata.initialize" => return encresp("{'result':200,'response':{}}"), + "userdata.set" => return encresp("{'result':200,'response':{}}"), + _ => return encresp("{'result':400,'response':{}}"), + } }, Err(err) => { // Handle deserialization error println!("Deserialization error: {}", err); - // Respond with a JSON error message or other appropriate response - return resp!(""); + // encrespond with a JSON error message or other appropriate response + return encresp("{'result':400,'response':{}}"); } } } diff --git a/utils/README.md b/utils/README.md index dcf465c..e1e2c1e 100644 --- a/utils/README.md +++ b/utils/README.md @@ -24,8 +24,15 @@ Decrypt: (key and iv are `0123456789012345` in hex format for openssl) -`openssl enc -d -aes-128-cfb -in aes.bin -out lol.txt -K '3031323334353637383930313233343536373839303132333435363738393031' -iv '30313233343536373839303132333435'` +`openssl enc -d -aes-128-cfb -in aes.bin -out lol.txt -K '30313233343536373839303132333435' -iv '30313233343536373839303132333435'` Oneliner: -`curl -X POST http://localhost/game | openssl enc -d -aes-128-cfb -K '30313233343536373839303132333435' -iv '3031323334353637383930313 -2333435'` +`curl -X POST http://localhost/game | openssl enc -d -aes-128-cfb -K '30313233343536373839303132333435' -iv '30313233343536373839303132333435'` + + +### Test a game command: +The python file pads the given protocol string, then openssl encrypts it for the server to then decrypt and respond. With the response we get, we are able to decrypt that using the same method. + +`python pad_plaintext.py '{"game":{"eventcode":"000","version":"2.4.1"},"param":{},"protocol":"unlock"}' | openssl enc -e -aes-128-cfb -K '30313233343536373839303132333435' -iv '30313233343536373839303132333435' | curl -X POST -H "Content-Type: application/octet-stream" --data-binary @- http://10.3.0.141/game | openssl enc -d -aes-128-cfb -K '30313233343536373839303132333435' -iv '30313233343536373839303132333435'` + +`python pad_plaintext.py '{"game":{"eventcode":"000","version":"2.4.1"},"param":{},"protocol":"unlock","terminal":{"tenpo_id":"1337","tenpo_index":1337,"terminal_attrib":0,"terminal_id":"1C1B0D07CDBB"}}' | openssl enc -e -aes-128-cfb -K '30313233343536373839303132333435' -iv '30313233343536373839303132333435' | curl -X POST -H "Content-Type: application/octet-stream" --data-binary @- http://localhost/game | openssl enc -d -aes-128-cfb -K '30313233343536373839303132333435' -iv '30313233343536373839303132333435'` diff --git a/utils/pad_plaintext.py b/utils/pad_plaintext.py new file mode 100644 index 0000000..f7ff77d --- /dev/null +++ b/utils/pad_plaintext.py @@ -0,0 +1,15 @@ +import sys + +def pkcs7_padding(data): + block_size = 16 # AES block size in bytes + padding_required = block_size - (len(data) % block_size) + padding = chr(padding_required).encode() * padding_required + return str.encode(data) + padding + +plaintext = str(sys.argv[1]) + +# Apply PKCS7 padding +padded_plaintext = pkcs7_padding(plaintext) + +# Output the padded plaintext to stdout so it can be piped into OpenSSL +sys.stdout.buffer.write(padded_plaintext)