第13节 第二种shellcode编写实战(2)

news2024/11/15 22:52:49

我最近在做一个关于shellcode入门和开发的专题课👩🏻‍💻,主要面向对网络安全技术感兴趣的小伙伴。这是视频版内容对应的文字版材料,内容里面的每一个环境我都亲自测试实操过的记录,有需要的小伙伴可以参考🫡

我的个人主页:https://imbyter.com

一、C语言方式编写shellcode

在第二种shellcode编写实战(1)的基础上,新增加一个CAPI类,将所有用到的函数都在这个类中做动态调用的处理,这样使得整个shellcode功能结构更加清晰。

1. 新建类CAPI(即api.h和api.cpp两个文件):

api.h:

#pragma once

#include <windows.h>
#include <Winternl.h>

class CAPI
{
private:
    HMODULE GetKernel32BaseAddress();
    FARPROC _GetPorcAddress();

public:
    void InitFunctions();

public:
    typedef HANDLE(WINAPI* FN_CreateFileA)(
        _In_ LPCSTR lpFileName,
        _In_ DWORD dwDesiredAccess,
        _In_ DWORD dwShareMode,
        _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
        _In_ DWORD dwCreationDisposition,
        _In_ DWORD dwFlagsAndAttributes,
        _In_opt_ HANDLE hTemplateFile);
    typedef int (WINAPI* FN_MessageBoxA)(
        __in_opt HWND hWnd,
        __in_opt LPCSTR lpText,
        __in_opt LPCSTR lpCaption,
        __in UINT uType);
    typedef HMODULE(WINAPI* FN_LoadLibraryA)(
        __in LPCSTR lpLibFileName);

public:
    FN_CreateFileA CreateFileA;
    FN_MessageBoxA MessageBoxA;
    FN_LoadLibraryA LoadLibraryA;
};

api.cpp:

#include "api.h"

// 获取kernel32基址
HMODULE CAPI::GetKernel32BaseAddress()
{
    HMODULE hKernel32 = NULL;

    // 用户保存模块名
    WCHAR wszModuleName[MAX_PATH];

#ifdef _WIN64    // 64位PEB偏移为0x60
    PPEB lpPeb = (PPEB)__readgsqword(0x60);
#else            // 32位PEB偏移为0x30
    PPEB lpPeb = (PPEB)__readfsdword(0x30);
#endif

    PLIST_ENTRY pListHead = &lpPeb->Ldr->InMemoryOrderModuleList;
    PLIST_ENTRY pListData = pListHead->Flink;

    // 遍历所有模块
    while (pListData != pListHead)
    {
        PLDR_DATA_TABLE_ENTRY pLDRData = CONTAINING_RECORD(pListData, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);

        DWORD dwLen = pLDRData->FullDllName.Length / 2;
        if (dwLen > 12)    // 12 是"kernel32.dll"的长度,获取到的完整路径肯定要比模块名长
        {
            // 从获取到的模块完整路径中提取模块名
            for (size_t i = 0; i < 12; i++)
            {
                wszModuleName[11 - i] = pLDRData->FullDllName.Buffer[dwLen - 1 - i];
            }

            // 最终要获取的目标模块名("kernel32.dll"),逐个字节比较,包含大小写。
            if ((wszModuleName[0] == 'k' || wszModuleName[0] == 'K') &&
                (wszModuleName[1] == 'e' || wszModuleName[1] == 'E') &&
                (wszModuleName[2] == 'r' || wszModuleName[2] == 'R') &&
                (wszModuleName[3] == 'n' || wszModuleName[3] == 'N') &&
                (wszModuleName[4] == 'e' || wszModuleName[4] == 'E') &&
                (wszModuleName[5] == 'l' || wszModuleName[5] == 'L') &&
                (wszModuleName[6] == '3') &&
                (wszModuleName[7] == '2') &&
                (wszModuleName[8] == '.') &&
                (wszModuleName[9] == 'd' || wszModuleName[9] == 'D') &&
                (wszModuleName[10] == 'l' || wszModuleName[10] == 'L') &&
                (wszModuleName[11] == 'l' || wszModuleName[11] == 'L'))
            {
                hKernel32 = (HMODULE)pLDRData->DllBase;
                break;
            }
        }
        pListData = pListData->Flink;
    }
    return hKernel32;
}

// 获取GetPorcAddress函数地址
FARPROC CAPI::_GetPorcAddress()
{
    // 保存最终结果
    FARPROC pGetPorcAddress = NULL;

    // kernel32基址
    HMODULE hKernel32 = GetKernel32BaseAddress();
    if (!hKernel32)
    {
        return NULL;
    }

    PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hKernel32;
    PIMAGE_NT_HEADERS lpNTHeader = (PIMAGE_NT_HEADERS)((unsigned char*)hKernel32 + lpDosHeader->e_lfanew);

    // 模块有效性验证
    if (!lpNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
    {
        return NULL;
    }
    if (!lpNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
    {
        return NULL;
    }

    // 通过导出表中的导出函数名,定位"GetProcAddress"的位置
    PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)((unsigned char*)hKernel32 + lpNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    PDWORD lpdwFunName = (PDWORD)((unsigned char*)hKernel32 + lpExports->AddressOfNames);
    PWORD lpdwOrd = (PWORD)((unsigned char*)hKernel32 + lpExports->AddressOfNameOrdinals);
    PDWORD lpdwFunAddr = (PDWORD)((unsigned char*)hKernel32 + lpExports->AddressOfFunctions);

    for (DWORD dwLoop = 0; dwLoop <= lpExports->NumberOfNames - 1; dwLoop++)
    {
        char* pFunName = (char*)(lpdwFunName[dwLoop] + (unsigned char*)hKernel32);
        // 比较函数名
        if (
            pFunName[0] == 'G' &&
            pFunName[1] == 'e' &&
            pFunName[2] == 't' &&
            pFunName[3] == 'P' &&
            pFunName[4] == 'r' &&
            pFunName[5] == 'o' &&
            pFunName[6] == 'c' &&
            pFunName[7] == 'A' &&
            pFunName[8] == 'd' &&
            pFunName[9] == 'd' &&
            pFunName[10] == 'r' &&
            pFunName[11] == 'e' &&
            pFunName[12] == 's' &&
            pFunName[13] == 's'
            )
        {
            pGetPorcAddress = (FARPROC)(lpdwFunAddr[lpdwOrd[dwLoop]] + (unsigned char*)hKernel32);
            break;
        }
    }
    return pGetPorcAddress;
}

// 初始化所有用到的函数
void CAPI::InitFunctions()
{
    // 获取GetPorcAddress函数地址
    typedef FARPROC(WINAPI* FN_GetProcAddress)(__in HMODULE hModule, __in LPCSTR lpProcName);
    FN_GetProcAddress fn_GetProcAddress = (FN_GetProcAddress)_GetPorcAddress();
    if (fn_GetProcAddress)
    {
        // 获取LoadLibraryA函数地址
        char szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 };
        LoadLibraryA = (FN_LoadLibraryA)fn_GetProcAddress(GetKernel32BaseAddress(), szLoadLibraryA);
        if (LoadLibraryA)
        {
            // 获取MessageBoxA函数地址
            char szUser32[] = { 'U','s','e','r','3','2','.','d','l','l',0 };
            char szMessageBoxA[] = { 'M','e','s','s','a','g','e','B','o','x','A',0 };
            MessageBoxA = (FN_MessageBoxA)fn_GetProcAddress(LoadLibraryA(szUser32), szMessageBoxA);
            
            // 获取CreateFileA函数地址
            char szCreateFileA[] = { 'C','r','e','a','t','e','F','i','l','e','A',0 };
            CreateFileA = (FN_CreateFileA)fn_GetProcAddress(GetKernel32BaseAddress(), szCreateFileA);
        }
    }
}

2. 在CAPI中,使用InitFunctions函数来初始化所有shellcode中用到的函数,在shellcode执行功能处,进行如下调用即可(a.start.cpp):

#include "a.start.h"
#include "shellcode.h"
#include "api.h"

void ShellCodeStart()
{
    CAPI api;
    // 初始化所有用到的函数
    api.InitFunctions();

    CDoShellcode shellcode;

    // 创建文件
    shellcode.DoCreateFile(&api);

    // 弹框提示
    shellcode.DoMessageBox(&api);

    // 其他功能...
}

3. 在类CDoShellcode中,将所有函数功能执行的参数都传递一个CAPI的指针变量,那么所有功能都可以使用CAPI中的函数。比如CDoShellcode中的DoCreateFile方法:

// 功能:创建文件 D:\1.txt
int CDoShellcode::DoCreateFile(CAPI* api)
{
    // 执行动态CreateFileA,创建文件
    char szFilePath[] = { 'D',':','\\','1','.','t','x','t',0 };
    api->CreateFileA(szFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);

    return 0;
}

如此一来,对类CDoShellcode而言,我们只关注功能的实现,不必再顾及函数动态调用的问题。所有用到的动态函数的实现都可以共享CAPI中的实现。

项目结构:

两个类:

  • CDoShellcode(shellcode.h和shellcode.cpp):shellcode执行的各类功能;
  • CAPI(api.h和api.cpp):所有shellcode使用到的动态函数。

    如果有任何问题,可以在我们的知识社群中提问和沟通交流:

    图片​​

    一个人走得再快,不如一群人走得更远!🤜🤛


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1679826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

错误: 找不到或无法加载主类问题(已解决)

今天在虚拟机中安装了idea2023.2的版本&#xff0c;运行代码时发现错误找不到主类&#xff01; 直接说结论&#xff1a; 我先clean了一下target&#xff0c;然后重新build&#xff0c;发现maven报错了&#xff0c;idea2023.2默认使用了内置的maven&#xff0c;然后我切换了一下…

Shell之(数组)

目录 一、shell数组 1.数组的定义 2.定义数组的方法 第一种 第二种 第三种 第四种 3.数组分片 4. 数组字符替换 临时替换 永久替换 5.删除数组 删除指定的下标 删除整组 6.数组遍历和重新定义 7.数组追加元素 方式一&#xff1a;指定位置添加 方法二&a…

【JAVA入门】Day05 - 面向对象

【JAVA入门】Day05 - 面向对象 文章目录 【JAVA入门】Day05 - 面向对象一、对象的设计和使用1.1 类和对象1.2 类的分类 二、封装三、private 关键字四、this 关键字五、构造方法六、JavaBean七、对象的内存图7.1 一个对象的内存图7.2 两个对象的内存图7.3 两个引用指向同一个对…

文心一言 VS 讯飞星火 VS chatgpt (252)-- 算法导论18.2 5题

五、因为叶结点无需指向孩子结点的指针&#xff0c;那么对同样大小的磁盘页面&#xff0c;可选用一个与内部结点不同的(更大的) t 值。请说明如何修改 B 树的创建和插人过程来处理这个变化。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 当我们在B树&#xff…

低空经济:无人机竞赛详解

无人机竞赛市场近年来呈现出蓬勃发展的态势&#xff0c;其市场价值不仅体现在竞赛本身&#xff0c;还体现在推动无人机技术创新、拓展应用场景以及促进产业链发展等多个方面。 一、比赛项目介绍 无人机竞赛通常分为多个项目&#xff0c;包括竞速赛、技巧赛、航拍赛等。每个项目…

slugify,slug格式转换工具

目录 前言 安装 特性 基本功能 生成简单的Slug 处理特殊字符 Unicode支持 高级功能 自定义替换规则 过滤停用词 使用不同的分隔符 处理多种语言 实际应用场景 网站和博客的SEO优化 电子商务平台的产品链接 数据清洗和预处理 总结 前言 在Web开发中&#xff0c;生成易于…

vm 虚拟机 Debian12 开启 root、ssh 登录功能

前言&#xff0c;安装的时候语言就选中文就好了。选择中文&#xff0c;在安装的时候就可以选择国内 163 的源。 开启 ssh 功能 先提权&#xff0c;用 root 账户 su安装 ssh 安装 ssh-server apt install openssh-server启动 ssh systemctl start ssh查看 ssh 状态 systemctl st…

景源畅信电商:做抖音有哪些未开发的蓝海领域?

在互联网信息爆炸的今天&#xff0c;抖音已经成为人们获取信息和娱乐的重要渠道。然而&#xff0c;随着用户数量的增加和内容的丰富&#xff0c;抖音的红海竞争也日益激烈。在这样的背景下&#xff0c;寻找还未被充分开发的蓝海领域&#xff0c;对于内容创作者来说&#xff0c;…

yolov8 模型架构轻量化 | 极致降参数量

模型轻量化加速是深度学习领域的重要研究方向&#xff0c;旨在减小模型的体积和计算复杂度&#xff0c;从而提高在资源受限设备上的运行效率&#xff0c;模型参数量在轻量化加速中扮演着至关重要的角色。 首先&#xff0c;模型参数量直接决定了模型的复杂度和存储空间需求。随…

西南大学计算机考研,选学硕还是专硕?西南大学计算机考研考情分析!

西南大学&#xff08;Southwest University&#xff09;是教育部直属&#xff0c;教育部、农业农村部、重庆市共建的重点综合大学&#xff0c;是国家首批"双一流"建设高校&#xff0c;"211工程"和"985工程优势学科创新平台"建设高校。现任党委书…

JVM学习-虚拟机栈

虚拟机栈 每个线程创建时都会创建一个虚拟机栈&#xff0c;其内部保存一个个栈帧&#xff0c;对应一次次Java方法调用&#xff0c;栈是线程私有的。 生命周期: 与线程相同 作用 主管Java程序的运行&#xff0c;它保存方法的局部变量、部分结果、并参与方法的调用和返回。 …

【Linux】系统登录,调用shell,shell配置文件,shell命令,特殊符号,shell快捷键,Linux运行级别,解决无限登录问题,修改提示符

目录 Linux系统的登录方式 以及 调用shell Linux shell 以及 shell配置文件 shell 命令 shell 特殊符号 shell 快捷键 Linux操作系统运行级别 单用户模式下解决无限登录问题 centos7修改命令行提示符 PS1 补充、centos7没有滚动条 Linux系统的登录方式 以及 调用shell…

怎样让猫给啥吃啥?生骨肉冻干拌粮哪有猫咪不吃的!

随着科学养猫的普及&#xff0c;生骨肉冻干喂养越来越受欢迎&#xff0c;生骨肉冻干喂养对猫的好处很多&#xff0c;它符合猫咪的天性&#xff0c;可以提供全面的营养&#xff0c;保持牙齿和牙龈的健康&#xff0c;还有助于维持健康的消化系统。然而&#xff0c;许多猫主人在选…

构建智能化不动产管理系统:数字化引领未来房地产行业发展

随着城市化进程的不断推进和房地产市场的持续发展&#xff0c;不动产管理系统的重要性日益凸显。在这一背景下&#xff0c;构建智能化不动产管理系统成为推动房地产行业数字化转型的关键举措。本文将深入探讨智能化不动产管理系统的构建与优势&#xff0c;助力房地产企业把握数…

深入剖析Tomcat(八) 载入器与打破双亲委派机制的自定义类加载器

写这篇文章让我头大了好几天&#xff0c;书中描述的内容倒是不多&#xff0c;可能也是那会Tomcat的现状。如今Tomcat发展了好多代&#xff0c;加上springboot的广泛应用&#xff0c;导致现在的类加载的步骤和Tomcat资料中描述的大相径庭。可能也是由于微服务的发展&#xff0c;…

Linux 第三十四章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

五丰黎红引领新营销模式:布局一物一码数字化营销,提高调味品销量和复购率

调味品行业的销售渠道主要有餐饮、家庭消费和食品加工&#xff0c;按销售额的占比约为6&#xff1a;3&#xff1a;1&#xff0c;餐饮行业是调味品行业的供需主力。在餐饮行业中&#xff0c;“大厨”这一角色具有十分重要的地位。因此&#xff0c;借助大厨的力量成为了许多调味品…

HCIP【VLAN综合实验】

目录 一、实验拓扑图&#xff1a; 二、实验要求&#xff1a; 三、实验思路&#xff1a; 四、实验步骤&#xff1a; 1、在交换机SW1,SW2,SW3配置VLAN和各个接口对应类型的配置 2、在路由器上面配置DHCP服务 一、实验拓扑图&#xff1a; 二、实验要求&#xff1a; 1、PC1 …

MT2057 门票

思路&#xff1a; 此题是求有多少个区间的平均值>t&#xff0c; 那么可以把每个值-t。如果新的数列的某个区间的和>0&#xff0c;那么说明这个区间满足条件。 令新数列的前缀和为b[i]&#xff0c;所以求[i, j]区间是否满足条件&#xff0c;即求b[j]-b[i-1]是否>0&am…

基于SSM的婚恋网站的设计与实现(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的婚恋网站的设计与实现&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spri…