Shellcode 执行示例:如何将二进制文件作为代码执行
该代码的功能是将一个二进制文件作为 shellcode 执行,其大致流程如下:
- 首先定义了一个 'payload' 函数,该函数在后面的 'loader' 中被执行;
- 'loader' 函数将 'payload' 函数的地址获取到,并将其内存页属性设置为可执行;
- 在 Windows 下,使用 'DllMain' 函数触发 'loader' 的执行,在 Linux 下,使用 '_init' 函数触发 'loader' 的执行;
- 在 'main' 函数中,读取 'payload.bin' 文件内容,并获取其内存地址;
- 使用 'syscall.Syscall' 函数执行 'payload',即将 'payload' 作为 shellcode 执行。
需要注意的是,该代码主要是为了演示如何将二进制文件作为 shellcode 执行,并不具备实际应用的意义,因为这种做法极易被恶意程序利用,造成严重的安全问题。
代码分析:
package main
/*
#cgo windows LDFLAGS: -lkernel32
#ifdef _WIN32
#include <windows.h>
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif
DLL_EXPORT void payload();
void loader() {
void* payload_addr = (void*)payload;
DWORD old_protect;
VirtualProtect(payload_addr, (SIZE_T) sizeof(payload), PAGE_EXECUTE_READWRITE, &old_protect);
// execute payload
void (*payload_func)() = (void (*)()) payload_addr;
payload_func();
}
#ifdef _WIN32
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
loader();
return TRUE;
}
#else
void _init() {
loader();
}
#endif
*/
import "C"
import (
"io/ioutil"
"unsafe"
)
func main() {
// read the payload from file
payload, err := ioutil.ReadFile("payload.bin")
if err != nil {
panic(err)
}
// get the memory address of the payload
payloadAddr := unsafe.Pointer(&payload[0])
// load the payload as a shellcode
_, _, err = syscall.Syscall(
uintptr(payloadAddr),
uintptr(len(payload)),
0,
0,
)
if err != nil {
panic(err)
}
}
代码功能:
payload函数:定义了一个空的函数,用于存放 shellcode。loader函数:获取payload函数的地址,并将其内存页属性设置为可执行,然后调用payload函数。DllMain函数(Windows)/_init函数(Linux):用于在程序启动时调用loader函数。main函数:读取 'payload.bin' 文件内容,获取其内存地址,并使用syscall.Syscall函数执行 shellcode。
安全风险:
将二进制文件作为 shellcode 执行存在以下安全风险:
- 代码容易被恶意程序利用,造成安全漏洞。
- 难以进行代码审计,增加了代码安全风险。
- 难以进行代码调试,增加了代码维护难度。
建议:
在实际应用中,不建议使用这种方法执行代码。如果需要执行二进制文件,建议使用安全可靠的执行方式,例如使用系统提供的 API 或库函数。
原文地址: https://www.cveoy.top/t/topic/lKP9 著作权归作者所有。请勿转载和采集!