(好难,被薄纱了QAQ)
RE test your Debugger 直接动态调试在提示的位置打断点
得结果
略
CompileMe!!! 文件打开以后是sln源代码文件??甚至不用逆向? 打开之后:完型填空?
看起来是一个简单的XTEA,但是vs一开就崩溃,vscode也不知道为什么不能运行。。。那先看看题(补全后):
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 namespace NSSCTF { internal class Program { static void Main (string [] args ) { var key = new ulong [] { 0x57656c636f6d6520 , 0x746f204e53534354 , 0x4620526f756e6423 , 0x3136204261736963 }; var c = new ulong [] { 0xc60b34b2bff9d34a , 0xf50af3aa8fd96c6b , 0x680ed11f0c05c4f1 , 0x6e83b0a4aaf7c1a3 , 0xd69b3d568695c3c5 , 0xa88f4ff50a351da2 , 0x5cfa195968e1bb5b , 0xc4168018d92196d9 }; const ulong e = 0x9E3779B9 ; var delta = Enumerable.Range(0 , 32 ).Select(index => e * (32 - (uint )index)).ToArray(); var decryptedBlocks = c.Select((block, index) => new { Value = block, Index = index }) .GroupBy(item => item.I ndex / 2 ) .Select(group => { ulong b1 = group .ElementAt(0 ).Value; ulong b2 = group .ElementAt(1 ).Value; ulong sum = e * 32 ; delta.ToList().ForEach(currentDelta => { b2 -= (((b1 << 4 ) ^ (b1 >> 5 )) + b1) ^ (sum + key[(sum >> 11 ) & 3 ]); sum -= e; b1 -= (((b2 << 4 ) ^ (b2 >> 5 )) + b2) ^ (sum + key[sum & 3 ]); }); return new [] { b1, b2 }; }) .SelectMany(block => block) .ToArray(); ulong [] decryptedText = new ulong [decryptedBlocks.Length]; Array.Copy(decryptedBlocks, decryptedText, decryptedText.Length); decryptedText.SelectMany(block => BitConverter.GetBytes(new ZZZ(block).GetVal()).Reverse()).ToList().ForEach(byteValue => Console.Write(Encoding.ASCII.GetString(new [] { byteValue })));
但是逻辑可以看懂,可以尝试用C重写一遍代码
但是后面有一个调用zzz
1 2 3 4 5 6 7 8 class ZZZ (ulong val ) : ZZY (val ){ public override ulong GetVal () { base .GetVal(); return val + 0x413FD584E295889 ; } }
而ZZZ到A的一万六千行代码都是类似这个的函数
(事后才发现这里调用的代码是base.GetVal()只是调用了继承自ZZY的getval函数然而没有返回值到确定的变量)
那么就需要用一个函数来读取并输出:
1 2 3 4 5 6 7 8 9 10 lines = open ('Program.cs' ,'rb' ).readlines() a = b'unsigned __int64 (unsigned __int64 val) {\n' c = b'}' for line in lines: if line.startswith(b' return val' ): a += b' val = ' +line[18 :] a += c print (a)open ('c.py' ,'wb' ).write(a)
然后复制这个函数到解密里面并调用。
最后的代码是
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 #include <stdio.h> #include <Windows.h> void dec (unsigned __int64 *a) { unsigned __int64 b2; unsigned __int64 b1; b1 = *a; b2 = a[1 ]; unsigned int e = 0x9E3779B9 ; unsigned __int64 key[4 ] = { 0x57656c636f6d6520 , 0x746f204e53534354 , 0x4620526f756e6423 , 0x3136204261736963 }; unsigned __int64 sum = 0 ; for (int i = 0 ; i < 32 ; ++i) { sum += e; } for (int i = 0 ; i < 32 ; ++i) { b2 -= (((b1 << 4 ) ^ (b1 >> 5 )) + b1) ^ (sum + key[(sum >> 11 ) & 3 ]); sum -= e; b1 -= (((b2 << 4 ) ^ (b2 >> 5 )) + b2) ^ (sum + key[sum & 3 ]); } *a = b1; a[1 ] = b2; } unsigned __int64 ccc (unsigned __int64 val) { ...... return val; } int main (void ) { unsigned __int64 Q[8 ] = { 0xc60b34b2bff9d34a , 0xf50af3aa8fd96c6b , 0x680ed11f0c05c4f1 , 0x6e83b0a4aaf7c1a3 , 0xd69b3d568695c3c5 , 0xa88f4ff50a351da2 , 0x5cfa195968e1bb5b , 0xc4168018d92196d9 }; for (int k = 0 ; k < 4 ; k++) { dec(&Q[k*2 ]); Q[k * 2 ] = ccc(Q[k * 2 ]); Q[k * 2 +1 ] = ccc(Q[k * 2 +1 ]); } for (int i = 0 ; i < 8 ; i++) printf ("%#llx,\n" , Q[i]); for (int i = 0 ; i < 8 ; i++) printf ("%s" , &Q[i]); getchar(); }
1 2 3 4 5 6 7 8 0x4e53534354467b35 ,0x384d745534695478 ,0x34754b7538505648 ,0x4559795939613774 ,0x5a30646171564966 ,0x4a5656396b704d52 ,0x5a37757644475948 ,0x52754a35384d7a7d
1 NSSCTF {58 MtU4iTx4uKu8PVHEYyY9a7tZ0daqVIfJVV9kpMRZ7uvDGYHRuJ58Mz}
CRYPTO pr 打开题
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 from Crypto.Util.number import *import randomflag=plaintext = 'NSSCTF{****************}' charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' padding_length = 100 - len (plaintext) for _ in range (padding_length): plaintext += random.choice(charset) e = 31413537523 message = bytes_to_long(plaintext.encode()) assert message > (1 << 512 )assert message < (1 << 1024 )prime_p = getPrime(512 ) prime_q = getPrime(512 ) prime_r = getPrime(512 ) n1 = prime_p * prime_q n2 = prime_q * prime_r ciphertext1 = pow (message, e, n1) ciphertext2 = pow (message, e, n2) print ('c1=' , ciphertext1)print ('c2=' , ciphertext2)print ('p=' , prime_p)print ('r=' , prime_r)''' c1= 36918910341116680090654563538246204134840776220077189276689868322808977412566781872132517635399441578464309667998925236488280867210758507758915311644529399878185776345227817559234605958783077866016808605942558810445187434690812992072238407431218047312484354859724174751718700409405142819140636116559320641695 c2= 15601788304485903964195122196382181273808496834343051747331984997977255326224514191280515875796224074672957848566506948553165091090701291545031857563686815297483181025074113978465751897596411324331847008870832527695258040104858667684793196948970048750296571273364559767074262996595282324974180754813257013752 p= 12101696894052331138951718202838643670037274599483776996203693662637821825873973767235442427190607145999472731101517998719984942030184683388441121181962123 r= 10199001137987151966640837133782537428248507382360655526592866939552984259171772190788036403425837649697437126360866173688083643144865107648483668545682383 '''
1 2 3 4 5 6 7 8 过程: 取质数p,q,r e = ... n1 = pq n2 = qr c1 = m^e mod n1 c2 = m^e mod n2 已知c1,c2,e,p,r求m
根据 $$ \begin{cases} c_1\equiv m^e(\mod n_1)\\ c_2\equiv m^e(\mod n_2) \end{cases} $$ 和同余定理 $$ 若a-b是n的倍数,那么a和b在\mod n下同余 $$ 因为原式可得 $$ \begin{cases} c_1-m^e=kpq\\ c_2-m^e=kqr \end{cases} $$ 所以 $$ \begin{cases} c_1\equiv m^e(\mod p)\\ c_2\equiv m^e(\mod r) \end{cases} $$ 所以 $$ \begin{cases} m^e\equiv c_1(\mod p)\\ m^e\equiv c_2(\mod r) \end{cases} $$ 根据中国剩余定理可以直接求m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from Crypto.Util.number import *from gmpy2 import invertc1 = 36918910341116680090654563538246204134840776220077189276689868322808977412566781872132517635399441578464309667998925236488280867210758507758915311644529399878185776345227817559234605958783077866016808605942558810445187434690812992072238407431218047312484354859724174751718700409405142819140636116559320641695 c2 = 15601788304485903964195122196382181273808496834343051747331984997977255326224514191280515875796224074672957848566506948553165091090701291545031857563686815297483181025074113978465751897596411324331847008870832527695258040104858667684793196948970048750296571273364559767074262996595282324974180754813257013752 p = 12101696894052331138951718202838643670037274599483776996203693662637821825873973767235442427190607145999472731101517998719984942030184683388441121181962123 r = 10199001137987151966640837133782537428248507382360655526592866939552984259171772190788036403425837649697437126360866173688083643144865107648483668545682383 e = 31413537523 n = p*r j1 = invert(r,p) j2 = invert(p,r) a = c1*j1*r+c2*j2*p d = invert(e, (p-1 )*(r-1 )) last = pow (a,d,n) print (long_to_bytes(last))