2024.7.17

目录

一.参数分离

1.1使用参数分离传递文件路径与进程名

1.2使用参数分离实现功能模块(-I,-d之类的)

二.动态调用

2.1VirtualAlloc动态调用

2.2其他敏感API的动态调用

三.Shellcode(bin文件)加密

四.心得体会 

一.参数分离

1.1使用参数分离传递文件路径与进程名

在许多编程语言中,特别是在命令行应用程序中,可以使用参数来传递文件路径和进程名。这种方式允许程序接受用户提供的输入,并据此进行相应的操作。以C语言为例,说明如何实现参数分离传递文件路径与进程名:

#include <stdio.h>
int main(int argc, char *argv[]) {
    if (argc &lt; 3) {
        printf("Usage: %s <process_name><file_path>\n", argv[0]);
        return 1;
    }

    char *process_name = argv[1];
    char *file_path = argv[2];

    printf("Process Name: %s\n", process_name);
    printf("File Path: %s\n", file_path);

    // 在这里可以使用 process_name 和 file_path 进行相应的操作

    return 0;
}

在C语言中,可以通过 argc 和 argv 参数来获取命令行传递的参数信息。通常,argv[0] 存储的是程序的名称,而 argv[1] 及之后的元素存储的是传递给程序的参数。

1.2使用参数分离实现功能模块(-I,-d之类的)

int main(int argc, char* argv[]) {
    if (strcmp(argv[1], "-i") == 0) {
        if (argc == 4) {
            printf("Injecting!!!\n");
            Inject(argv);
        }
        else {
            wprintf(L"注入方式:-i 路径 进程名\n");
        }
    }
    if (strcmp(argv[1], "-d") == 0) {
        Normal(argv[2]);
    };
    if (strcmp(argv[1], "-h") == 0) {
        printf("-i Inject\n-h help\n-d normal\n");
    }
}

此代码的运行要与下图所示内容搭配使用

 以上述代码为例,若在红圈圈的地方输入-i box.dll,则会出现以下情况:

若是输入-h则会出现以下结果:

若输入-d box.dll则会出现以下结果: 

二.动态调用

2.1VirtualAlloc动态调用

保留、提交或更改调用进程的虚拟地址空间中页面区域的状态。 此函数分配的内存会自动初始化为零。若要在另一进程的地址空间中分配内存,请使用 VirtualAllocEx 函数。

语法如下:

LPVOID VirtualAlloc(
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);

参数

[in, optional] lpAddress

要分配的区域的起始地址。 如果保留内存,则指定的地址向下舍入到分配粒度中最近的倍数。 如果内存已保留并正在提交,地址将向下舍入到下一页边界。 若要确定页面的大小和主机计算机上的分配粒度,请使用 GetSystemInfo 函数。 如果此参数 NULL,系统将确定分配区域的位置。

如果此地址位于未通过调用 InitializeEnclave初始化的 enclave 中,VirtualAlloc 为该地址的 enclave 分配零页。 该页必须以前未提交,并且不会使用 Intel Software Guard Extensions 编程模型的 EEXTEND 指令进行测量。

如果地址位于初始化的 enclave 中,则分配操作将失败,并出现 ERROR_INVALID_ADDRESS 错误。 对于不支持动态内存管理的 enclave(即 SGX1),这是事实。 SGX2 enclave 将允许分配,并且该页必须在分配后由 enclave 接受。

[in] dwSize

区域的大小(以字节为单位)。 如果 lpAddress 参数 NULL,则此值向上舍入到下一页边界。 否则,分配的页面将包含范围中包含一个或多个字节的所有页面,从 lpAddress 到 lpAddress+dwSize。 这意味着跨页边界的 2 字节范围会导致这两个页面都包括在分配的区域。

[in] flAllocationType

内存分配的类型。 此参数必须包含以下值之一。

2.2其他敏感API的动态调用

在C++中,"API调用"通常指的是使用外部库或操作系统提供的应用程序接口(API)来执行特定的功能。具体的API调用方式取决于您要调用的API的类型,例如操作系统API、第三方库API或者网络服务的API。这里我会简要介绍几种常见的情况:

1. 操作系统API调用

操作系统提供了一些API,允许程序直接访问操作系统的底层功能,如文件操作、进程管理、网络通信等。这些API通常通过操作系统的头文件和库来访问。
例如,Windows操作系统提供了一系列的WinAPI函数,可以在C++中直接调用。这些函数包含在 <windows.h> 头文件中,您可以通过这些函数来执行诸如文件读写、窗口创建、注册表访问等操作。

#include <windows.h>
#include <iostream>

int main() {
    // 使用WinAPI打开一个文件
    HANDLE hFile = CreateFile(
        L"C:\\path\\to\\file.txt",  // 文件路径
        GENERIC_READ,                // 访问权限
        FILE_SHARE_READ,             // 共享模式
        NULL,                        // 安全描述符
        OPEN_EXISTING,               // 打开已存在文件
        FILE_ATTRIBUTE_NORMAL,       // 文件属性
        NULL                         // 模板文件句柄
    );

    if (hFile == INVALID_HANDLE_VALUE) {
        std::cerr <<"Failed to open file!" << std::endl;
        return 1;
    }

    // 文件操作完成后记得关闭文件句柄
    CloseHandle(hFile);

    return 0;
}

2. 第三方库API调用

在C++中,可以使用第三方库来扩展程序的功能。这些库通常提供了一组API,允许进行特定领域的操作,如图形处理、数据库访问、图像处理等。通常情况下,需要包含相应的头文件并链接库文件来使用这些API。 

#include <opencv2/opencv.hpp>

int main() {
    cv::Mat image = cv::imread("image.jpg", cv::IMREAD_COLOR);

    if (image.empty()) {
        std::cerr << "Failed to open image file!"<< std::endl;
        return 1;
    }

    cv::imshow("Image", image);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

3. 网络服务API调用

在C++中,通过网络服务的API可以与远程服务器进行通信,如HTTP请求、数据传输等。通常可以使用标准库或者特定的网络库来实现这些功能。
例如,使用C++标准库中的网络功能进行简单的HTTP GET请求

#include <iostream>
#include <curl/curl.h>

int main() {
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://api.example.com/data");
        res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            std::cerr <<"Failed to perform HTTP request: " <<curl_easy_strerror(res) <<std::endl;
        }
        curl_easy_cleanup(curl);
    }

    return 0;
}

三.Shellcode(bin文件)加密

1.与服务器连接:

2.制作 stager

 3.正常执行进程注入后被445监听

  

四.心得体会 

        Shellcode注入进程是一项涉及计算机安全和系统编程的实验,通过该实验我深刻体会到了系统级编程和安全工具的重要性。在这个实验中,我学到了以下几点重要的体会和经验:

       首先,理解Shellcode的基本原理和作用是非常重要的。Shellcode是一段编写精练、通常用于利用系统漏洞或实现攻击的机器代码。它们通常以十六进制表示,并且非常紧凑,因此理解其结构和如何编写是学习注入技术的第一步。

      其次,掌握注入技术涉及到操作系统底层编程的理解和技能。在实验中,我需要理解操作系统的进程内存布局、堆栈结构和程序计数器等底层概念。

      在实施注入时,我学会了如何利用编程语言编写工具来执行注入操作。这些工具需要能够打开目标进程、分配内存空间、将Shellcode写入目标进程的地址空间,并且最终执行Shellcode。这不仅仅是对编程技能的挑战,还要求对操作系统API和系统调用有深入理解。

      在注入过程中,我遇到了许多挑战和错误。例如,可能会遇到内存保护机制的限制,需要采取额外的措施来绕过这些保护机制。此外,还需要考虑Shellcode的兼容性和平台差异,以确保在不同的操作系统或架构上都能正确执行。

     最重要的是,在进行这项实验的过程中,我深刻意识到了安全意识和实施安全措施的重要性。注入技术本身可以用于恶意目的,因此在学习和实验时,必须遵循道德准则和法律法规,确保技术的合法和道德使用。

    总的来说,Shellcode注入进程的实验不仅仅是技术的探索,更是对操作系统和计算机安全理念的深入了解。通过这个实验,我不仅提升了自己的技术能力,还加深了对系统级编程和安全工具的理解和应用。

  • 17
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值