设为首页 加入收藏

TOP

1.12 进程注入ShellCode套接字(一)
2023-09-09 10:25:48 】 浏览:224
Tags:1.12 程注入 ShellCode

在笔者前几篇文章中我们一直在探讨如何利用Metasploit这个渗透工具生成ShellCode以及如何将ShellCode注入到特定进程内,本章我们将自己实现一个正向ShellCodeShell,当进程被注入后,则我们可以通过利用NC等工具连接到被注入进程内,并以对方的权限及身份执行命令,该功能有利于于Shell的隐藏。本章的内容其原理与《运用C语言编写ShellCode代码》中所使用的原理保持一致,通过动态定位到我们所需的网络通信函数并以此来构建一个正向Shell,本章节内容对Metasploit工具生成的Shell原理的理解能够起到促进作用。

读者需要理解,套接字(socket)是计算机网络中一种特殊的文件,是网络通信中的一种技术,用于实现进程之间的通信和网络中数据的传输。在网络通信中,套接字就像一条传送数据的管道,负责数据的传输和接收。而socket(套接字)是在网络通信中最常用的一种通信协议,它定义了一组用于网络通信的API。通过使用socket,程序员可以在不同的计算机之间进行通信。读者可以将两者理解为一个意思。

1.12.1 读入Kernel32模块基址

为了能让读者更清晰的认识功能实现细节,首先笔者先来实现一个简单的读取特定模块内函数的入口地址,并输出该模块地址的功能,需要注意的是,在之前的文章中笔者已经介绍了这种读取技术,当时使用的是汇编版实现,由于需要自定位代码的支持导致汇编语言的实现过于繁琐,其实此类代码在应用层实现仅仅只需要调用GetProcAddress()即可获取到核心参数,其实先细节如下所示;

#include <iostream>
#include <Windows.h>

// Kernel32 调用约定定义
typedef HMODULE(WINAPI* LOADLIBRARY)(LPCTSTR lpFileName);
typedef FARPROC(WINAPI* GETPROCADDRESS) (HMODULE hModule, LPCSTR lpProcName);

typedef struct _ShellBase
{
  // 针对Kernel32的操作
  HANDLE KernelHandle;        // 存储句柄
  char kernelstring[20];      // 存储字符串 kernel32.dll

  // 针对User32的操作
  HANDLE UserHandle;         // 存储句柄    
  char userstring[20];       // 存储字符串 user32.dll

  // 定义函数指针
  LOADLIBRARY KernelLoadLibrary;
  GETPROCADDRESS KernelGetProcAddress;
}ShellParametros;

int main(int argc,char *argv[])
{
  ShellParametros Param;
  
  // 得到加载基地址的工具函数
  Param.KernelHandle = LoadLibrary("kernel32.dll");
  Param.KernelLoadLibrary = (LOADLIBRARY)GetProcAddress((HINSTANCE)Param.KernelHandle, "LoadLibraryA");
  Param.KernelGetProcAddress = (GETPROCADDRESS)GetProcAddress((HINSTANCE)Param.KernelHandle, "GetProcAddress");
  
  printf("获取到Kernel32.dll = 0x%08X \n", Param.KernelHandle);

  system("pause");
  return 0;
}

这段代码主要是定义了一个结构体ShellParametros,并初始化了其中的一些参数。该结构体中定义了两个HANDLE类型的变量KernelHandleUserHandle,分别用于存储kernel32.dlluser32.dll的句柄。同时,也定义了两个字符串数组kernelstringuserstring,用于存储对应的库名。

接下来,定义了两个函数指针类型LOADLIBRARYGETPROCADDRESS,分别用于后续的动态库加载和函数导出操作。

main函数中,首先初始化了ShellParametros结构体类型的变量Param。然后,调用LoadLibrary函数加载kernel32.dll库,并通过GetProcAddress函数分别获取LoadLibraryAGetProcAddress函数的地址,并将它们赋值给Param.KernelLoadLibraryParam.KernelGetProcAddress函数指针变量。最终打印出获取到的kernel32.dll的基地址,以及等待用户按下任意键退出程序。

该代码拆分来看,首先是入口处的结构体定义部分,这部分定义了一个结构体ShellParametros,其中包含了对于kernel32.dlluser32.dll库的操作的句柄和字符串,以及相关的函数指针类型LOADLIBRARYGETPROCADDRESS

// Kernel32 调用约定定义
typedef HMODULE(WINAPI* LOADLIBRARY)(LPCTSTR lpFileName);
typedef FARPROC(WINAPI* GETPROCADDRESS) (HMODULE hModule, LPCSTR lpProcName);

typedef struct _ShellBase
{
    // 针对Kernel32的操作
    HANDLE KernelHandle;        // 存储句柄
    char kernelstring[20];      // 存储字符串 kernel32.dll

    // 针对User32的操作
    HANDLE UserHandle;         // 存储句柄    
    char userstring[20];       // 存储字符串 user32.dll

    // 定义函数指针
    LOADLIBRARY KernelLoadLibrary;
    GETPROCADDRESS KernelGetProcAddress;
}ShellParametros;

而在主函数中,首先声明了一个结构体变量Param,然后调用LoadLibrary函数加载kernel32.dll库,将得到的句柄存储到Param.KernelHandle中。接着通过调用GetProcAddress函数获取LoadLibraryAGetProcAddress函数的地址,将得到的函数地址分别存储到Param.KernelLoadLibraryParam.KernelGetProcAddress中。最后通过printf函数打印出获取到的Kernel32.dll的基址。

int main(int argc, char *argv[])
{
    ShellParametros Param;

    // 得到加载基地址的工具函数
    Param.KernelHandle = LoadLibrary("kernel32.d
首页 上一页 1 2 3 4 5 6 下一页 尾页 1/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++算法之旅、03 语法篇 | 全内容 下一篇C++算法之旅、04 基础篇 | 第一章..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目