├── .gitignore ├── AES_Killer - Mobile App Demo ├── aes-hook.js ├── android │ ├── app-release.apk │ └── my_activity.java ├── frida-hook.py └── node js server │ └── nodejs-server.js ├── AES_Killer-NodeJS-DemoApp ├── demo.html └── server.js └── SRePlay ├── api └── v9 │ └── api.php └── index.php /.gitignore: -------------------------------------------------------------------------------- 1 | AES_Killer-NodeJS-DemoApp/node_modules 2 | AES_Killer-NodeJS-DemoApp/package-lock.json 3 | -------------------------------------------------------------------------------- /AES_Killer - Mobile App Demo/aes-hook.js: -------------------------------------------------------------------------------- 1 | // code borrowed from https://zhuanlan.zhihu.com/p/320229007 2 | 3 | 'use strict;' 4 | 5 | console.log("Script loaded successfully ..... "); 6 | 7 | function bytesToString(arr) { 8 | var str = ''; 9 | arr = new Uint8Array(arr); 10 | for (var i in arr) { 11 | str += String.fromCharCode(arr[i]); 12 | } 13 | return str; 14 | } 15 | 16 | function bytesToHex(arr) { 17 | var str = ''; 18 | var k, j; 19 | for (var i = 0; i < arr.length; i++) { 20 | k = arr[i]; 21 | j = k; 22 | if (k < 0) { 23 | j = k + 256; 24 | } 25 | if (j < 16) { 26 | str += "0"; 27 | } 28 | str += j.toString(16); 29 | } 30 | return str; 31 | } 32 | 33 | var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', 34 | base64DecodeChars = new Array((-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), 62, (-1), (-1), (-1), 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, (-1), (-1), (-1), (-1), (-1), (-1), (-1), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, (-1), (-1), (-1), (-1), (-1), (-1), 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, (-1), (-1), (-1), (-1), (-1)); 35 | 36 | function bytesToBase64(e) { 37 | var r, a, c, h, o, t; 38 | for (c = e.length, a = 0, r = ''; a < c;) { 39 | if (h = 255 & e[a++], a == c) { 40 | r += base64EncodeChars.charAt(h >> 2), 41 | r += base64EncodeChars.charAt((3 & h) << 4), 42 | r += '=='; 43 | break 44 | } 45 | if (o = e[a++], a == c) { 46 | r += base64EncodeChars.charAt(h >> 2), 47 | r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4), 48 | r += base64EncodeChars.charAt((15 & o) << 2), 49 | r += '='; 50 | break 51 | } 52 | t = e[a++], 53 | r += base64EncodeChars.charAt(h >> 2), 54 | r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4), 55 | r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6), 56 | r += base64EncodeChars.charAt(63 & t) 57 | } 58 | return r 59 | } 60 | 61 | 62 | 63 | Java.perform(function () { 64 | var secretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec'); 65 | secretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (a, b) { 66 | var result = this.$init(a, b); 67 | console.log("================= SecretKeySpec ====================="); 68 | console.log("SecretKeySpec :: bytesToString :: " + bytesToString(a)); 69 | console.log("SecretKeySpec :: bytesToBase64 :: " + bytesToBase64(a)); 70 | console.log("SecretKeySpec :: bytesToBase64 :: " + bytesToHex(a)); 71 | return result; 72 | } 73 | 74 | 75 | var ivParameterSpec = Java.use('javax.crypto.spec.IvParameterSpec'); 76 | ivParameterSpec.$init.overload('[B').implementation = function (a) { 77 | var result = this.$init(a); 78 | console.log("\n================== IvParameterSpec ===================="); 79 | console.log("IvParameterSpec :: bytesToString :: " + bytesToString(a)); 80 | console.log("IvParameterSpec :: bytesToBase64 :: " + bytesToBase64(a)); 81 | console.log("IvParameterSpec :: bytesToBase64 :: " + bytesToHex(a)); 82 | return result; 83 | } 84 | 85 | var cipher = Java.use('javax.crypto.Cipher'); 86 | cipher.getInstance.overload('java.lang.String').implementation = function (a) { 87 | var result = this.getInstance(a); 88 | console.log("\n======================================"); 89 | console.log("Cipher :: " + a); 90 | return result; 91 | } 92 | 93 | cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (a, b, c) { 94 | var result = this.init(a, b, c); 95 | console.log("\n================ cipher.init() ======================"); 96 | 97 | if (N_ENCRYPT_MODE == '1') 98 | { 99 | console.log("init :: Encrypt Mode"); 100 | } 101 | else if(N_DECRYPT_MODE == '2') 102 | { 103 | console.log("init :: Decrypt Mode"); 104 | } 105 | 106 | console.log("Mode :: " + a); 107 | console.log("Secret Key :: " + bytesToHex(b)); 108 | console.log("Secret Key :: " + bytesToBase64(b)); 109 | console.log("IV Param :: " + bytesToHex(c)); 110 | console.log("IV Param :: " + bytesToBase64(c)); 111 | 112 | return result; 113 | } 114 | 115 | cipher.doFinal.overload("[B").implementation = function (x) { 116 | console.log("\n================ doFinal() ======================"); 117 | var ret = cipher.doFinal.overload("[B").call(this, x); 118 | console.log("doFinal :: data to encrypt/decrypt - base64 :: " + bytesToBase64(x)); 119 | console.log("doFinal :: data ro encrypt/decrypt - string :: " + bytesToString(x)); 120 | 121 | return ret; 122 | } 123 | 124 | 125 | 126 | 127 | 128 | }); -------------------------------------------------------------------------------- /AES_Killer - Mobile App Demo/android/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d3vilbug/demo-example-code-snippets/dca9b79eae78e45092954a062e33404916e2a8a4/AES_Killer - Mobile App Demo/android/app-release.apk -------------------------------------------------------------------------------- /AES_Killer - Mobile App Demo/android/my_activity.java: -------------------------------------------------------------------------------- 1 | package com.example.a11x256.frida_test; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.util.Base64; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.EditText; 9 | import android.widget.TextView; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.DataOutputStream; 13 | import java.io.IOException; 14 | import java.io.InputStreamReader; 15 | import java.io.UnsupportedEncodingException; 16 | import java.net.HttpURLConnection; 17 | import java.net.MalformedURLException; 18 | import java.net.URL; 19 | import java.security.InvalidAlgorithmParameterException; 20 | import java.security.InvalidKeyException; 21 | import java.security.NoSuchAlgorithmException; 22 | 23 | import javax.crypto.BadPaddingException; 24 | import javax.crypto.Cipher; 25 | import javax.crypto.IllegalBlockSizeException; 26 | import javax.crypto.NoSuchPaddingException; 27 | import javax.crypto.spec.IvParameterSpec; 28 | import javax.crypto.spec.SecretKeySpec; 29 | 30 | public class my_activity extends AppCompatActivity { 31 | EditText username_et; 32 | EditText password_et; 33 | TextView message_tv; 34 | HttpURLConnection conn; 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_my_activity); 40 | message_tv = ((TextView) findViewById(R.id.textView)); 41 | username_et = (EditText) findViewById(R.id.editText); 42 | password_et = (EditText) findViewById(R.id.editText2); 43 | ((Button) findViewById(R.id.button)).setOnClickListener(new View.OnClickListener() { 44 | @Override 45 | public void onClick(View v) { 46 | send_data(username_et.getText() + ":" + password_et.getText()); 47 | } 48 | }); 49 | 50 | } 51 | 52 | void send_data(final String data) { 53 | URL url = null; 54 | try { 55 | url = new URL("http://192.168.18.134"); 56 | final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 57 | conn.setRequestMethod("POST"); 58 | conn.setDoOutput(true); 59 | new Thread(new Runnable() { 60 | @Override 61 | public void run() { 62 | try { 63 | DataOutputStream out = new DataOutputStream(conn.getOutputStream()); 64 | out.writeBytes(enc(data)); 65 | BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); 66 | final String text = in.readLine(); 67 | runOnUiThread(new Runnable() { 68 | @Override 69 | public void run() { 70 | ((TextView) findViewById(R.id.textView)).setText(text); 71 | dec(text); 72 | } 73 | }); 74 | } catch (IOException e) { 75 | e.printStackTrace(); 76 | } 77 | } 78 | }).start(); 79 | 80 | } catch (MalformedURLException e) { 81 | e.printStackTrace(); 82 | } catch (IOException e) { 83 | e.printStackTrace(); 84 | } 85 | 86 | } 87 | 88 | String enc(String data) { 89 | try { 90 | String pre_shared_key = "aaaaaaaaaaaaaaaa"; //assume that this key was not hardcoded 91 | String generated_iv = "bbbbbbbbbbbbbbbb"; 92 | Cipher my_cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); 93 | my_cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(pre_shared_key.getBytes("UTF-8"), "AES"), new IvParameterSpec(generated_iv.getBytes("UTF-8"))); 94 | byte[] x = my_cipher.doFinal(data.getBytes()); 95 | 96 | System.out.println(new String(Base64.encode(x, Base64.DEFAULT))); 97 | return new String(Base64.encode(x, Base64.DEFAULT)); 98 | } catch (NoSuchAlgorithmException e) { 99 | e.printStackTrace(); 100 | } catch (InvalidKeyException e) { 101 | e.printStackTrace(); 102 | } catch (InvalidAlgorithmParameterException e) { 103 | e.printStackTrace(); 104 | } catch (NoSuchPaddingException e) { 105 | e.printStackTrace(); 106 | } catch (BadPaddingException e) { 107 | e.printStackTrace(); 108 | } catch (UnsupportedEncodingException e) { 109 | e.printStackTrace(); 110 | } catch (IllegalBlockSizeException e) { 111 | e.printStackTrace(); 112 | } 113 | return null; 114 | } 115 | 116 | String dec(String data) { 117 | try { 118 | byte[] decoded_data = Base64.decode(data.getBytes(), Base64.DEFAULT); 119 | String pre_shared_key = "aaaaaaaaaaaaaaaa"; //assume that this key was not hardcoded 120 | String generated_iv = "bbbbbbbbbbbbbbbb"; 121 | Cipher my_cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); 122 | my_cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(pre_shared_key.getBytes("UTF-8"), "AES"), new IvParameterSpec(generated_iv.getBytes("UTF-8"))); 123 | String plain = new String(my_cipher.doFinal(decoded_data)); 124 | return plain; 125 | } catch (UnsupportedEncodingException e) { 126 | e.printStackTrace(); 127 | } catch (NoSuchPaddingException e) { 128 | e.printStackTrace(); 129 | } catch (InvalidAlgorithmParameterException e) { 130 | e.printStackTrace(); 131 | } catch (NoSuchAlgorithmException e) { 132 | e.printStackTrace(); 133 | } catch (InvalidKeyException e) { 134 | e.printStackTrace(); 135 | } catch (BadPaddingException e) { 136 | e.printStackTrace(); 137 | } catch (IllegalBlockSizeException e) { 138 | e.printStackTrace(); 139 | } 140 | return ""; 141 | } 142 | } -------------------------------------------------------------------------------- /AES_Killer - Mobile App Demo/frida-hook.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | import frida 4 | 5 | 6 | def on_message(a, b): 7 | print("on message ....... ") 8 | 9 | 10 | 11 | # Android Application borrowed from 12 | # https://github.com/11x256/frida-android-examples/tree/master/examples/5 13 | 14 | 15 | device = frida.get_usb_device() 16 | pid = device.spawn(["com.example.a11x256.frida_test"]) 17 | device.resume(pid) 18 | time.sleep(1) 19 | session = device.attach(pid) 20 | 21 | # session = frida.get_usb_device().attach('com.example.a11x256.frida_test') 22 | with open("aes-hook.js") as f: 23 | script = session.create_script(f.read()) 24 | script.on("message", on_message) 25 | script.load() 26 | 27 | sys.stdin.read() 28 | 29 | -------------------------------------------------------------------------------- /AES_Killer - Mobile App Demo/node js server/nodejs-server.js: -------------------------------------------------------------------------------- 1 | var http = require("http"); 2 | var crypto = require('crypto'); 3 | var qs = require('querystring'); 4 | 5 | var key= 'aaaaaaaaaaaaaaaa'; 6 | var iv = 'bbbbbbbbbbbbbbbb'; 7 | http.createServer(function(request , response) 8 | { 9 | var body = ''; 10 | request.on('data' , function(data){ 11 | 12 | body+=data; 13 | }); 14 | 15 | console.log(body) 16 | response.writeHead(200,""); 17 | request.on('end', function(){ 18 | console.log(body); 19 | var enc = '' ; 20 | var cipher = crypto.createCipheriv('aes-128-cbc' , key , iv); 21 | enc +=cipher.update("Can you see this secret message too !!!","utf8" , "binary"); 22 | enc += cipher.final("binary"); 23 | console.log(enc); 24 | response.end(new Buffer(enc, 'binary').toString('base64')); 25 | }); 26 | 27 | 28 | 29 | } 30 | 31 | 32 | ).listen(1337, "127.0.0.1"); 33 | console.log("NodeJS server started on port 127.0.0.1:1337 ......."); -------------------------------------------------------------------------------- /AES_Killer-NodeJS-DemoApp/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | AES Killer - Demo App 4 | 5 | 6 | 7 | 8 | 9 | 10 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 |
219 |
220 |

AES Killer Demo App

221 |
222 | 223 | 224 |
225 |
226 | 227 |
228 |
Complete Request & Response request
229 |
230 | 231 |
232 |
233 | 234 | 235 |
236 |
237 | 238 |
239 |
240 | 241 | 242 |
243 |
244 | 245 |
246 | 247 |
248 | 249 |
250 |
251 |
252 | 253 |
254 |
Specific Request Parameters and complete response
255 |
256 | 257 |
258 |
259 | 260 | 261 |
262 |
263 | 264 |
265 |
266 | 267 | 268 |
269 |
270 | 271 |
272 | 273 |
274 | 275 |
276 | 277 |
278 | 279 | 280 | 281 |
282 | 283 | 284 | 285 | 286 |
287 |
288 | 289 |
290 |
Specific JSON Request parameters & complete response
291 |
292 | 293 |
294 |
295 | 296 | 297 |
298 |
299 | 300 |
301 |
302 | 303 | 304 |
305 |
306 | 307 |
308 | 309 |
310 | 311 |
312 |
313 |
314 | 315 |
316 |
Specific Request and Response Parameters
317 |
318 | 319 |
320 |
321 | 322 | 323 |
324 |
325 | 326 |
327 |
328 | 329 | 330 |
331 |
332 | 333 |
334 | 335 |
336 | 337 |
338 | 339 |
340 | 341 | 342 | 343 | 344 |
345 | 346 | 347 | 348 | 349 | 350 |
351 |
352 | 353 |
354 |
Override Request & Response (Variant-01)
355 |
356 | 357 |
358 |
359 | 360 | 361 |
362 |
363 | 364 |
365 |
366 | 367 | 368 |
369 |
370 | 371 |
372 | 373 |
374 | 375 |
376 | 377 |
378 |
379 | 380 |
381 |
Override Request & Response (Variant-02)
382 |
383 | 384 |
385 |
386 | 387 | 388 |
389 |
390 | 391 |
392 |
393 | 394 | 395 |
396 |
397 | 398 |
399 | 400 |
401 | 402 |
403 | 404 |
405 | 406 | 407 |
408 | 409 | 410 | -------------------------------------------------------------------------------- /AES_Killer-NodeJS-DemoApp/server.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | const path = require("path") 3 | const bodyParser = require('body-parser'); 4 | const CryptoJS = require("crypto-js"); 5 | const cors = require("cors"); 6 | 7 | const _secret_key = "aaaaaaaaaaaaaaaa"; // YWFhYWFhYWFhYWFhYWFhYQ== 8 | const _iv_param = "bbbbbbbbbbbbbbbb"; // YmJiYmJiYmJiYmJiYmJiYg== 9 | 10 | function do_encrypt(_str){ 11 | var key = CryptoJS.enc.Utf8.parse(_secret_key); 12 | var iv = CryptoJS.enc.Utf8.parse(_iv_param); 13 | var enc_data = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(_str), key, { keySize: 128 / 8, iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); 14 | return enc_data.toString(); 15 | } 16 | 17 | function do_decrypt(_str){ 18 | var key = CryptoJS.enc.Utf8.parse(_secret_key); 19 | var iv = CryptoJS.enc.Utf8.parse(_iv_param); 20 | var plain_text = CryptoJS.AES.decrypt(_str, key, { keySize: 128 / 8, iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); 21 | return plain_text.toString(CryptoJS.enc.Utf8); 22 | } 23 | 24 | 25 | const app = express(); 26 | app.use("/v1_login", bodyParser.text({type:"*/*"})); 27 | app.use("/v2_login", bodyParser.urlencoded({ extended: true })); 28 | app.use("/v3_login", bodyParser.json()); 29 | app.use("/v4_login", bodyParser.json()); 30 | app.use("/v6_login", bodyParser.json()); 31 | app.use(bodyParser.urlencoded({ extended: true })); 32 | 33 | app.use(cors({ origin: '*'})); 34 | 35 | 36 | app.get("/", (req, res) =>{ 37 | res.sendFile(path.join(__dirname + "/demo.html")); 38 | }) 39 | 40 | app.post("/v1_login", (req, res) => { 41 | // console.log(req.body); 42 | var dec_body = (do_decrypt(req.body)); 43 | console.log(dec_body); 44 | var res_data = "you sent :: " + dec_body.toString(); 45 | var enc_res_data = do_encrypt(res_data).toString(); 46 | // console.log(res_data); 47 | // console.log(enc_res_data); 48 | res.write(enc_res_data); 49 | // res.sendStatus(200); 50 | res.end(); 51 | 52 | }); 53 | 54 | 55 | app.post("/v2_login", (req, res) => { 56 | console.log("username :: " + req.body.username); 57 | console.log("password :: " + req.body.password); 58 | 59 | var _username = do_decrypt(req.body.username); 60 | var _password = do_decrypt(req.body.password); 61 | 62 | var res_body = "you sent :: username=" + _username + " :: password="+_password 63 | res.write(do_encrypt(res_body)); 64 | res.end(); 65 | 66 | }); 67 | 68 | app.post("/v3_login", (req, res) => { 69 | console.log("username :: " + req.body.username); 70 | console.log("password :: " + req.body.password); 71 | 72 | var _username = do_decrypt(req.body.username); 73 | var _password = do_decrypt(req.body.password); 74 | 75 | var res_body = "you sent :: username=" + _username + " :: password="+_password 76 | 77 | res.write(res_body); 78 | res.end(); 79 | 80 | }); 81 | 82 | app.post("/v4_login", (req, res) => { 83 | console.log("username :: " + req.body.username); 84 | console.log("password :: " + req.body.password); 85 | 86 | var _username = do_decrypt(req.body.username); 87 | var _password = do_decrypt(req.body.password); 88 | 89 | var res_body = '{ "username":"' + do_encrypt(_username) + '","password":"' + do_encrypt(_password) + '"}'; 90 | 91 | res.write(res_body); 92 | res.end(); 93 | 94 | }); 95 | 96 | app.post("/v5_login", (req, res) => { 97 | console.log("data :: " + req.body.data); 98 | var _data = do_decrypt(req.body.data); 99 | 100 | console.log(_data); 101 | res.write("{\"data\":\"" + do_encrypt(_data) + "\"}"); 102 | res.end(); 103 | 104 | }); 105 | 106 | app.post("/v6_login", (req, res) => { 107 | console.log("data :: " + req.body.data); 108 | var _data = do_decrypt(req.body.data); 109 | 110 | console.log(_data); 111 | res.write("data=" + do_encrypt(_data)); 112 | res.end(); 113 | 114 | }); 115 | 116 | 117 | 118 | app.listen(3000) 119 | console.log("Express server started on port 3000 ...... "); 120 | 121 | 122 | -------------------------------------------------------------------------------- /SRePlay/api/v9/api.php: -------------------------------------------------------------------------------- 1 | true, "data"=>$data, "token"=>genToken()); 54 | 55 | } else { 56 | $res = array("success"=>false, "data"=>"Invalid Token"); 57 | } 58 | 59 | echo json_encode($res); 60 | 61 | ?> -------------------------------------------------------------------------------- /SRePlay/index.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 15 | 16 | PHP Replay Protection 17 | 18 | 23 | 24 | 40 | 41 | 42 | 43 | 44 |
45 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | --------------------------------------------------------------------------------