吐槽 强网被冲烂了,一堆破事,0xweek4没打完,阿西,继续努力
Reverse 绯想天则 unity逆向基于mono,分析dll
winflag被搬了,rsa加密
第二段对应公钥,第三段对应私钥
解密
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 from cryptography.hazmat.primitives import serialization, hashesfrom cryptography.hazmat.primitives.asymmetric import rsa, paddingimport base64 private_key_xml = """<RSAKeyValue> <Modulus>jR+j5ZyLvbOyQRZgJQtHl5slRSQ4igoTQrKrwnmIwOcrkc48RQ6qD6wFXYAbFmiu34YpO638surG2dFemO0+vSoJuFksK70amen3pdilSgUukdFZ3SEJ/7QoeWls40exLsVPn3zWclN5b1ESaL4TN0MpC9lJUuWqkwiYSU2fZYQg9Z7S05RcVtl0JgK9O/DmLjW6+t6RdUAyo+9gsPXdGNOd/f4LyOTbj0iaWg2aCGfZhz3UtqACS2q6L9p1a9L3vYgLNpp1GnUcZnA+CVfhzcCWTHQ4X7hTuJsyysFEm/6tei3uBKYq6/HnTrmo2rSZxKS/GuExRO3A9hmyD+PEcw==</Modulus> <Exponent>AQAB</Exponent> <P>+6YUEMyFZlINlnZYRznRU0qU2Krb4QaFCUnNhFsL37y55rnz0/hLfLSA2FistQiMLy0Yz01fkxOTtwwkWkHikRu7KFi7vQzTg/KbdKNnHJ11huemk0DuwxDghj+3uNC30heSA6NFlF47zlge8AY2J+iQ8JpgJNsrfZYNRZ5txD0=</P> <Q>j5BSrK3Li9VaBvRn2UGMf8q2N0J7tbaRvQonHhU1uBQYlhifttmK5wr1PurZHsb7tiNIv0RluM9HaUbQ/CczqLskVKJNkwpVyGM2rydiqbZ/KaP00ytTiR7Hxd0GUC06Syfi2h1VwaEewAOTkRUo/DuKYugPSaiyqARipyhfRm8=</Q> <DP>0lwCagiNevscYKqNIP0z/mxaAMTTCUhp7VnEct+pDV62CClpqcflUlmRW0jFFpAOn2ETXDdRraCv2lRMDycEPkjwKsoCJgaSyboEOXxetYzqsdrzZCTjciypg4/ABL506yrI5EGX6G7dj6AaPIr0umeuwXJK7IRJ1rGYZpoJKAE=</DP> <DQ>HA4BCfughj/4KtnCHYOguCxd9WiJklYOHtoIEOnmKIXM1DAVrf7PFR1gFZ6BNXF/KPW2NqJgGoBvHRSYrF3gy31euSdKb4yafOFeg1X4AuBF81Y19rpFxcr9ER6DKFHeTWeK/kKzSnZ48t8ADF8NNlVQUsm0ixlraEgLG01ZaQM=</DQ> <InverseQ>qZwSExM5GW+CsTtvN2DPmwQtLf7cTA2DwY+8+4bnR7X0MTqssUDNtc8l+HD3uml9BRg9m4t1PoY+qGsh5qEtFsITBvt0pqNM5mdg8WrB1e85Xzpdvsfqvv1PN3KsDjduzkY0SazVBlur+OX86JTF3jSLFeFkornO1ckHcApqU54=</InverseQ> <D>LABbh/IhmAp5X9XsMGCt99VF76L1hgTSMI+pAkAGpa7uZM3a+OUznSNToO2ahIgrTkJ0hMkg62BMlAm15xTB5RVAZpxXK2QQ8UCEGM/N6aBn/ss5q7rrdTDlFcYLT2pBEoYu51lzO75PNKggh0wMjcSA/dLIC/LUFngtk12Cf5IRwsdn0Kc2aoiiHU0NtvWklLZGkzcs4VL5FI7n1yDeIS9I+lKA14dJUCEhAltfMMiTSq+vpzoSedOcc8V0v9O9mjef8W62DasLusKxCCQi6PzsLA7ul2yLuOWTi1oysnrUVZryOWTvMr2V3GC0wfGRdXajd6qwwKVvGUt72egeEQ==</D> </RSAKeyValue>""" cipher_text_base64 = "TxDTykBFS+ewdHSIKSRRw63i4/7Os3pHqvC/WOnnFPKupfz0VpUqFRVEgtOdfJLdcxNKBvc67E/nIqU4dz8L88DZB9xVaKawdDgJ8c3EhI//r1aZkzbN2hURFdsS1UoF932XT9wPW61TsXPX7UyFAG4IInifxQr6KU7hyQNHIkpBkYsTgp/wxH5/g6IKEff8H/zEjbLcalck5k/r3vG8DeBQkhZUQ4I5HfIyetUBAmZyr8sZkygErKxVaF6vWZZtoPBkLzCxY0WIoaYcTfp+n5q1dUBDOshvXhVf1M3KGokZL2PqXT9K9Gv91d8aazXq7MV1iqCN4AwWAeFPn8OIYg==" def decrypt_rsa_xml (private_key_xml, cipher_text_base64 ): from xml.etree import ElementTree as ET root = ET.fromstring(private_key_xml) def b64decode_tag (tag_name ): tag = root.find(tag_name) if tag is not None : return base64.b64decode(tag.text) return None modulus = b64decode_tag('Modulus' ) exponent = b64decode_tag('Exponent' ) p = b64decode_tag('P' ) q = b64decode_tag('Q' ) dp = b64decode_tag('DP' ) dq = b64decode_tag('DQ' ) inverse_q = b64decode_tag('InverseQ' ) d = b64decode_tag('D' ) def bytes_to_int (b ): return int .from_bytes(b, 'big' ) n = bytes_to_int(modulus) e = bytes_to_int(exponent) d = bytes_to_int(d) p = bytes_to_int(p) q = bytes_to_int(q) dp = bytes_to_int(dp) dq = bytes_to_int(dq) iq = bytes_to_int(inverse_q) private_key = rsa.RSAPrivateNumbers( p=p, q=q, d=d, dmp1=dp, dmq1=dq, iqmp=iq, public_numbers=rsa.RSAPublicNumbers(e=e, n=n) ).private_key() cipher_data = base64.b64decode(cipher_text_base64) plain_data = private_key.decrypt( cipher_data, padding.PKCS1v15() ) return plain_data.decode('utf-8' )try : plaintext = decrypt_rsa_xml(private_key_xml, cipher_text_base64) print ("解密成功!" ) print ("明文:" , plaintext)except Exception as ex: print ("解密失败:" , str (ex))
镜渊折枝 apk,解包后aes加密,native层的compare方法
对密文做了个处理
iv在secret.bin,frida跑下提取相关内容,注意hook时机
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 26 27 28 29 30 31 32 33 Java .perform (function ( ){ function bytesToHex (bytes ) { if (bytes === null || bytes.length === 0 ) return "(null)" ; let hex = '' ; for (let i = 0 ; i < bytes.length ; i++) { let b = bytes[i] & 0xff ; hex += ('0' + b.toString (16 )).slice (-2 ); } return hex; }; console .log ("hook 开始!" ); let FlagChecker = Java .use ("com.example.easynative.FlagChecker" ); console .log ("[+] 成功找到 FlagChecker 类!" ); FlagChecker ["encrypt" ].implementation = function (plainText, key, iv ) { console .log ("========================================" ); console .log ("[+] encrypt 被调用!" ); console .log (` plainText: ${plainText} ` ); console .log (` key (hex): ${bytesToHex(key)} ` ); console .log (` iv (hex) : ${bytesToHex(iv)} ` ); let result = this ["encrypt" ](plainText, key, iv); console .log (` result (hex): ${bytesToHex(result)} ` ); console .log ("========================================" ); return result; }; });
注意CTR模式
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 26 27 28 29 30 31 32 33 34 35 from Crypto.Cipher import AESimport binascii key_hex = '307867616d652d5365637265744b6579' iv_hex = '8aa5610c74411b11a35368de56bf6ab3' enc_hex = '38eb985938fe0a9f126f814d660b170751da248d02d0a838e884a5bc287a4f53c5e35a862b10da3a11a2631318441ed83031' key = binascii.unhexlify(key_hex) iv = binascii.unhexlify(iv_hex) ciphertext = binascii.unhexlify(enc_hex) cipher = AES.new(key, AES.MODE_CTR, nonce=iv[:8 ], initial_value=iv[8 :]) plaintext = cipher.decrypt(ciphertext)print ("🔑 Key (ASCII):" , key.decode('utf-8' , errors='ignore' ))print ("🔐 IV (Hex):" , iv_hex)print ("🔒 Ciphertext (Hex):" , enc_hex)print ("🔓 Plaintext (UTF-8):" , plaintext.decode('utf-8' , errors='replace' ))
花鸟风月 调试定位入口点去花
标准 jz/jnz + E8
第一次漏了一些地方,主要是第一个加密处理导致解密没成功
sub 8
call $+5
分析加密
patch v11推断前面为key处理
解密
key,跑挺久的,移位异或导致非线性了
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 26 27 28 from z3 import *def rol (x,n ): return (x<<n) | LShR(x,32 -n) solver=Solver() key=BitVec('key' ,32 ) v11=BitVec(0x81428113 ,32 ) shifts=[(i*13 )%32 for i in range (10 )]for i in range (10 ): v11=(0x1421043 *v11+0x43298815 ) & 0xFFFFFFFF key_tmp=rol(key,shifts[i]) v11^=key_tmp solver.add(v11==0xa745da5d )if solver.check() == sat: model = solver.model() key_value=model[key].as_long & 0xffffffff print (f'key_hex: {key_value:08x} ' )else : print ('无解' )
b64有改动,第二个与第三个换位了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import base64 enc='MAPDc3GtPQ34vM3pNBb1PWGxccHtvxH1NVa9JPTtacS57IilN5uxJSW5Iwm=' key=0x98BF3B77 e1=list (enc)for i in range (0 ,len (enc),4 ): e1[i+1 ],e1[i+2 ]=e1[i+2 ],e1[i+1 ] string='' .join(e1) e2=base64.b64decode(string) e2=bytearray (e2)for i in range (44 ): key_tmp=(key>>(8 *(i%4 ))) & 0xFF e2[i]^=((key_tmp>>4 ) | (key_tmp<<4 )) & 0xFF e2[i]^=key_tmp print (chr (e2[i]),end='' )