حل crackme من كاسبرسكي لاب

في أحد الأيام الجميلة ، بدأت قنوات مختلفة في البرق تلقي ارتباطًا بمصنّع الكراك من LK ، وستتم دعوة الذين أتموا المهمة بنجاح لإجراء مقابلة معهم! . بعد مثل هذا البيان الصريح ، تساءلت عن مدى صعوبة العكس. كيف يمكنني حل هذه المهمة يمكن قراءتها تحت خفض (الكثير من الصور).

بعد وصولي إلى المنزل ، قمت مجددًا بإعادة قراءة المهمة ، وقمت بتنزيل الأرشيف وبدأت في النظر إلى ما بداخلها. وداخله كان:



نبدأ x64dbg ، تفريغ بعد التفريغ ، انظر ما هو في الواقع داخل:





نأخذ اسم الملف من وسيطات سطر الأوامر -> فتح ، قراءة -> تشفير الخطوة الأولى -> تشفير الخطوة الثانية -> الكتابة إلى ملف جديد.

إنه بسيط ، لقد حان الوقت للنظر في التشفير.

لنبدأ مع stage1


في العنوان 0x4033f4 هناك وظيفة أسميتها crypt_64bit_up (فيما بعد ستفهم السبب) ، يطلق عليها من حلقة في مكان ما داخل stage1



وقليلا نتيجة التعقيم ملتوية



في البداية حاولت إعادة كتابة نفس الخوارزمية في بيثون ، وقتلتها لعدة ساعات واتضح شيئًا كهذا (والذي يجب أن يكون get_dword و byteswap واضحًا من الأسماء)

def _add(x1, x2): return (x1+x2) & 0xFFFFFFFF def get_buf_val(t, buffer): t_0 = t & 0xFF t_1 = (t >> 8) & 0xFF t_2 = (t >> 16) & 0xFF t_3 = (t >> 24) & 0xFF res = _add(get_dword(buffer, t_0 + 0x312), (get_dword(buffer, t_1 + 0x212) ^ _add(get_dword(buffer, t_2+0x112), get_dword(buffer, t_3+0x12)))) # print('Got buf val: 0x%X' % res) return res def crypt_64bit_up(initials, buffer): steps = [] steps.append(get_dword(buffer, 0) ^ byteswap(initials[0])) # = z steps.append(get_buf_val(steps[-1], buffer) ^ byteswap(initials[1]) ^ get_dword(buffer, 1)) for i in range(2, 17): steps.append(get_buf_val(steps[-1], buffer) ^ get_dword(buffer, i) ^ steps[i-2]) res_0 = steps[15] ^ get_dword(buffer, 17) res_1 = steps[16] print('Res[0]=0x%X, res[1]=0x%X' % (res_0, res_1)) 

ولكن بعد ذلك قررت الانتباه إلى الثوابت 0x12 ، 0x112 ، 0x212 ، 0x312 (بدون ست عشري 18 ، 274 ، 536 ... ليس مشابهًا جدًا لشيء غير عادي). نحن نحاول google لهم والعثور على مستودع كامل (تلميح: NTR) مع تنفيذ وظائف التشفير وفك التشفير ، وهذا هو التوفيق. نحاول تشفير ملف اختبار بمحتويات عشوائية في البرنامج الأصلي ، وإفراغه وتشفير الملف نفسه بنص صغير ، يجب أن يعمل كل شيء ، ويجب أن تكون النتائج كما هي. بعد ذلك ، نحاول فك تشفيره (قررت عدم الخوض في التفاصيل ونسخ وظيفة فك التشفير من المصدر فقط)

 def crypt_64bit_down(initials, keybuf): x = initials[0] y = initials[1] for i in range(0x11, 1, -1): z = get_dword(keybuf, i) ^ x x = get_buf_val(z, keybuf) x = y ^ x y = z res_0 = x ^ get_dword(keybuf, 0x01) # x - step[i], y - step[i-1] res_1 = y ^ get_dword(keybuf, 0x0) return (res_1, res_0) def stage1_unpack(packed_data, state): res = bytearray() for i in range(0, len(packed_data), 8): ciphered = struct.unpack('>II', packed_data[i:i+8]) res += struct.pack('>II', *crypt_64bit_down(ciphered, state)) return res 

ملاحظة مهمة: يختلف المفتاح في المستودع عن المفتاح في البرنامج (وهو منطقي تمامًا). لذلك ، بعد تهيئة المفتاح ، أنا فقط ألقيت به في ملف ، وهذا هو المخزن المؤقت / keybuf

نمر إلى الجزء الثاني


كل شيء أبسط من ذلك بكثير: أولاً ، يتم إنشاء مجموعة من الأحرف الفريدة بحجم 0x55 بايت في النطاق (33 ، 118) (الأحرف القابلة للطباعة) ، ثم يتم تجميع القيمة 32 بت في 5 أحرف قابلة للطباعة من الصفيف التي تم إنشاؤها مسبقًا.





نظرًا لعدم وجود عشوائي عند إنشاء المصفوفة المذكورة أعلاه ، في كل مرة يبدأ فيها البرنامج ، ستكون هذه المصفوفة هي نفسها ، ونفريغها بعد التهيئة ويمكننا فك حزمة stage_2 من خلال وظيفة بسيطة

 def stage2_unpack(packed_data, state): # checked! res = bytearray() for j in range(0, len(packed_data), 5): mapped = [state.index(packed_data[j+i]) for i in range(5)] res += struct.pack('>I', sum([mapped[4-i]*0x55**i for i in range(5)])) return res 

نحن نفعل شيئا مثل هذا:

 f = open('stage1.state.bin', 'rb') stage1 = f.read() f.close() f = open('stage2.state.bin', 'rb') stage2 = f.read() f.close() f = open('rprotected.dat', 'rb') packed = f.read() f.close() unpacked_from_2 = stage2_unpack(packed, stage2) f = open('unpacked_from_2', 'wb') f.write(unpacked_from_2) f.close() unpacked_from_1 = stage1_unpack(unpacked_from_2, stage1) f = open('unpacked_from_1', 'wb') f.write(unpacked_from_1) f.close() 

ونحصل على النتيجة

Source: https://habr.com/ru/post/ar431690/


All Articles