| (1/10) C++ CrackMe |
#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib")
// ============================================
// القيم الثابتة المستخرجة من الكود
// ============================================
// 1. الـ Salt الثابت (16 بايت)
const UCHAR pbSalt[] = {
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 2. الـ IV (Initialization Vector) - 16 بايت
const UCHAR pbIV[] = {
0xAE, 0xF8, 0x90, 0x80, 0xB8, 0x09, 0x96, 0x20,
0x48, 0xEC, 0x1A, 0x25, 0xF4, 0x05, 0xDE, 0x2A
};
// 3. البيانات المشفرة (Ciphertext) - 32 بايت (قسمين)
const UCHAR pbCiphertext[] = {
// الجزء الأول (xmmword_140032A1C)
0xBF, 0x65, 0x08, 0xD4, 0xE5, 0x24, 0xFB, 0xCB,
0xB6, 0x45, 0xDF, 0x1F, 0x84, 0x5D, 0x3B, 0x6F,
// الجزء الثاني (xmmword_140032D78)
0x70, 0x7C, 0x46, 0x09, 0x2D, 0xC2, 0x90, 0x5C,
0xE7, 0xFD, 0x89, 0x5F, 0xC5, 0x5B, 0x2D, 0x62
};
// 4. خوارزمية التجزئة (من sub_1400022E0)
const WCHAR* pszAlgId = L"SHA256"; // مستخرج من "expand 32-byte k"
// 5. عدد التكرارات لـ PBKDF2 (0x927C0 = 600,000)
const ULONGLONG cIterations = 600000;
// ============================================
// 6. دوال مساعدة (مستخرجة من الكود)
// ============================================
// دالة توليد المفتاح باستخدام PBKDF2 (من sub_140002D50)
NTSTATUS DeriveKeyFromPassword(
const CHAR* szPassword,
UCHAR* pbKey,
DWORD cbKeyLength
) {
NTSTATUS status;
BCRYPT_ALG_HANDLE hAlgorithm = NULL;
// فتح خوارزمية التجزئة
status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_SHA256_ALGORITHM, NULL, 0);
if (!NT_SUCCESS(status)) return status;
// استخراج المفتاح باستخدام PBKDF2
status = BCryptDeriveKeyPBKDF2(
hAlgorithm,
(PUCHAR)szPassword,
(ULONG)strlen(szPassword),
(PUCHAR)pbSalt,
sizeof(pbSalt),
cIterations,
pbKey,
cbKeyLength,
0
);
BCryptCloseAlgorithmProvider(hAlgorithm, 0);
return status;
}
// دالة فك التشفير باستخدام AES (من sub_140002D50)
NTSTATUS DecryptData(
const UCHAR* pbKey,
DWORD cbKeyLength,
const UCHAR* pbIV,
const UCHAR* pbCiphertext,
DWORD cbCiphertext,
UCHAR* pbPlaintext,
DWORD* pcbPlaintext
) {
NTSTATUS status;
BCRYPT_ALG_HANDLE hAlgorithm = NULL;
BCRYPT_KEY_HANDLE hKey = NULL;
UCHAR pbKeyObject[512] = { 0 };
DWORD cbKeyObject = 0, cbResult = 0;
// فتح خوارزمية AES
status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0);
if (!NT_SUCCESS(status)) return status;
// الحصول على حجم كائن المفتاح
DWORD cbData = 0;
status = BCryptGetProperty(hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&cbKeyObject, sizeof(cbKeyObject), &cbData, 0);
if (!NT_SUCCESS(status)) goto cleanup;
// إنشاء مفتاح التشفير
status = BCryptGenerateSymmetricKey(hAlgorithm, &hKey, pbKeyObject, sizeof(pbKeyObject), (PUCHAR)pbKey, cbKeyLength, 0);
if (!NT_SUCCESS(status)) goto cleanup;
// فك التشفير
status = BCryptDecrypt(
hKey,
(PUCHAR)pbCiphertext,
cbCiphertext,
NULL, // لا يوجد PaddingInfo
(PUCHAR)pbIV,
sizeof(pbIV),
pbPlaintext,
*pcbPlaintext,
&cbResult,
0
);
*pcbPlaintext = cbResult;
cleanup:
if (hKey) BCryptDestroyKey(hKey);
if (hAlgorithm) BCryptCloseAlgorithmProvider(hAlgorithm, 0);
return status;
}
// دالة المقارنة الآمنة (من sub_14000C900)
BOOL SecureCompare(
const UCHAR* pbData1,
const UCHAR* pbData2,
DWORD cbLength
) {
for (DWORD i = 0; i < cbLength; i++) {
if (pbData1[i] != pbData2[i]) return FALSE;
}
return TRUE;
}
// ============================================
// 7. الدالة الرئيسية (من sub_140001030)
// ============================================
int main() {
CHAR szPassword[256] = { 0 };
UCHAR pbKey[32] = { 0 };
UCHAR pbPlaintext[64] = { 0 };
DWORD cbPlaintext = sizeof(pbPlaintext);
NTSTATUS status;
printf("A simple guessing game!\n");
printf("Please guess the password: ");
// استقبال الإدخال (من sub_140001030)
if (scanf("%255s", szPassword) != 1) {
printf("Invalid input, quitting!\n");
return 0;
}
// ============================================
// 8. تنفيذ الخوارزمية الكاملة
// ============================================
// الخطوة 1: توليد المفتاح من كلمة المرور باستخدام PBKDF2
status = DeriveKeyFromPassword(szPassword, pbKey, sizeof(pbKey));
if (!NT_SUCCESS(status)) {
printf("Error deriving key: 0x%08X\n", status);
return 1;
}
// الخطوة 2: فك تشفير البيانات باستخدام المفتاح المستخرج
status = DecryptData(pbKey, sizeof(pbKey), pbIV, pbCiphertext, sizeof(pbCiphertext), pbPlaintext, &cbPlaintext);
if (!NT_SUCCESS(status)) {
printf("Error decrypting data: 0x%08X\n", status);
return 1;
}
// الخطوة 3: عرض النتيجة (الـ Flag)
printf("Decrypted data (length: %d bytes):\n", cbPlaintext);
for (DWORD i = 0; i < cbPlaintext; i++) {
printf("%c", pbPlaintext[i]);
}
printf("\n");
// ============================================
// 9. مقارنة مع القيمة المتوقعة (اختياري)
// ============================================
// القيمة المتوقعة للـ Flag (يجب استخراجها من الكود)
// مثال: "FLAG{...}"
// const UCHAR pbExpectedFlag[] = "FLAG{...}";
// if (SecureCompare(pbPlaintext, pbExpectedFlag, cbPlaintext)) {
// printf("Password is correct!\n");
// } else {
// printf("Password is incorrect!\n");
// }
return 0;
} |
2026-07-06 06:50 |