ShellCode详解三

直接进入正题。

在完成正式的shellcode代码导出之前,我们先手动的对代码进行导出,以使各位同学更加了解其原理。

手动注入shellcode

1、我们利用DLE工具找到上一节中我们生成的PE文件的代码段位置
在这里插入图片描述
上述图片就是我们的代码段位置
2、利用WinHex工具我们将这一段代码复制出来
在这里插入图片描述
通过以上步骤我们就已经将shellcode的代码复制到我们的剪切板了,当我们复制的代码注入到任何进程的时候它就会出现一个弹窗。
3、随便写一个可执行程序,然后将我们复制的代码注入进去,然后我们来看一下效果

#pragma comment(linker,"/entry:ShellCodeEntry")int ShellCodeEntry()
{return 0;
}

上边是一个简单的代码,什么也不做。
然后我们来看一下上一节我们写的shellcode生成的PE文件效果
在这里插入图片描述
是一个简单的弹窗。
使用x64dbg工具打开上述写的简单程序
首先,先看一下没有注入的情况:
在这里插入图片描述
可以看到,什么也没有发生,因为我们什么也没做,啥也没有是理所当然的了。
接下来,我们将我们的shellcode代码注入进去:
在这里插入图片描述
可以看到,当我们的shellcode注入进去后,它执行的就是我们写的shellcode代码。

现在我们手动对shellcode代码段复制并随便注入到一个进程的过程已经全部结束。当然,实际应用中我们当然不可能手动复制这段shellcode的代码段了,所以接下来就是重点了,我们可以依赖程序的自动提取,把shellcode的代码段提取出来,然后直接全选就可以了。重点!重点!重点!重要的事说三遍。

自动提取程序中的shellcode代码

首先,我们需要搞清楚一个问题,我们写的函数是如何保存到生成的PE文件中的,我们可以使用IDA看一下。实际上它就是以cpp文件的从上到下函数地址保存的,所以要获取我们的shellcode代码,我们就可以这么写:

#include <Windows.h>//定义函数入口点
#pragma comment(linker,"/entry:ShellCodeEntry")int ShellCodeEntry()
{HANDLE hFile = CreateFile(L"shellcode.bin", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);//shellcode代码段长度DWORD dwShellcodeSize = (DWORD)ShellCodeEnd - (DWORD)ShellCodeStart;DWORD dwRetSize;WriteFile(hFile, ShellCodeStart, dwShellcodeSize, &dwRetSize, NULL);CloseHandle(hFile);
#endifreturn 0;
}

其中需要注意的是"ShellCodeStart"就是我们shellcode代码的起始函数,"ShellCodeEnd"是我们结束的代码,它实际上是没有任何功能的,只是一个shellcode结束的标志。
全部代码如下:

#include <Windows.h>
#include <winternl.h>#pragma comment(linker,"/entry:ShellCodeEntry")HMODULE GetKernel32BaseAddress();
FARPROC GetPorcAddressBaseAddress();void ShellCodeStart()
{typedef FARPROC(WINAPI* FN_GetProcAddress)(_In_ HMODULE hModule, _In_ LPCSTR lpProcName);typedef HMODULE(WINAPI* FN_LoadLibraryA)(_In_ LPCSTR lpLibFileName);FN_GetProcAddress fn_GetProcAddress;fn_GetProcAddress = (FN_GetProcAddress)GetPorcAddressBaseAddress();if (!fn_GetProcAddress)return;FN_LoadLibraryA fn_LoadlibraryA;//LoadLibraryAchar szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 };HMODULE hKernel32Address = GetKernel32BaseAddress();fn_LoadlibraryA = (FN_LoadLibraryA)fn_GetProcAddress(hKernel32Address, szLoadLibraryA);if (!fn_LoadlibraryA)return;typedef int (WINAPI* FM_MessageBoxA)(__in_opt HWND hWnd, __in_opt LPCSTR lpText, __in_opt LPCSTR lpCaption, __in UINT uType);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 };FM_MessageBoxA fn_MessageBoxA = (FM_MessageBoxA)(fn_GetProcAddress(fn_LoadlibraryA(szUser32), szMessageBoxA));if (fn_MessageBoxA){char szText[] = { 'H','e','l','l','o',0 };fn_MessageBoxA(NULL, szText, 0, 0);}
}//获取kernel32的基址
HMODULE GetKernel32BaseAddress()
{HMODULE hKernel32 = NULL;//保存模块名WCHAR wszModuleName[MAX_PATH];#ifdef _WIN64//获取gs偏移60hPPEB lpPeb = (PPEB)__readgsqword(0x60);
#else//获取fs偏移30hPPEB 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){for (size_t i = 0; i < 12; i++){wszModuleName[11 - i] = pLDRData->FullDllName.Buffer[dwLen - 1 - i];}//kernel32.dllif ((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')){//kernel32.dll在进程中的基址hKernel32 = (HMODULE)pLDRData->DllBase;break;}}pListData = pListData->Flink;}return hKernel32;
}//获取GetPorcAddress地址
FARPROC GetPorcAddressBaseAddress()
{FARPROC pGetPorcAddress = NULL;HMODULE hKernel32 = GetKernel32BaseAddress();if (!hKernel32)return pGetPorcAddress;//获取Dos头PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hKernel32;//获取NT头PIMAGE_NT_HEADERS lpNtHeader = (PIMAGE_NT_HEADERS)((unsigned char*)hKernel32 + lpDosHeader->e_lfanew);if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size &&!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress){return pGetPorcAddress;}//导出表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; dwLoop++){char* pFunName = (char*)(lpdwFunName[dwLoop] + (unsigned char*)hKernel32);//GetProcAddressif (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 ShellCodeEnd()
{
}int ShellCodeEntry()
{HANDLE hFile = CreateFile(L"shellcode.bin", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);DWORD dwShellcodeSize = (DWORD)ShellCodeEnd - (DWORD)ShellCodeStart;DWORD dwRetSize;WriteFile(hFile, ShellCodeStart, dwShellcodeSize, &dwRetSize, NULL);CloseHandle(hFile);return 0;
}

如此,运行程序之后,我们的shellcode代码段就直接保存到"shellcode.bin"文件中了。
生成的文件内容如下:
在这里插入图片描述
可以看到,这个文件和我们的shellcode代码完全一样。

到这里,我们的shellcode生成基础基本就完事了。感谢大家的阅读,后边可能还会出一些高级的,大家期待吧… ^ _ ^

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

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

相关文章

Appium测试之获取appPackage和appActivity

appPackage和appActivity 进行appium自动化测试非常重要的两个参数&#xff0c;我们所测试的APP不同&#xff0c;这两个参数肯定也是不一样的。那如何快速的获取这APP的这两个参数呢&#xff1f;我这里介绍两个方法。 import org.openqa.selenium.remote.DesiredCapabilities;i…

韩国站群服务器在全球网络架构中的重要作用?

韩国站群服务器在全球网络架构中的重要作用? 在全球互联网的蓬勃发展中&#xff0c;站群服务器作为网络架构的核心组成部分之一&#xff0c;扮演着至关重要的角色。韩国站群服务器以其卓越的技术实力、优越的地理位置、稳定的网络基础设施和强大的安全保障能力&#xff0c;成…

docker(二):Centos安装docker

文章目录 1、安装docker2、启动docker3、验证 官方文档&#xff1a;https://docs.docker.com/engine/install/centos/ 1、安装docker 下载依赖包 yum -y install gcc yum -y install gcc-c yum install -y yum-utils设置仓库 yum-config-manager --add-repo http://mirrors…

端到端将重塑智驾?获10亿美金融资,解密英国AI独角兽Wayve

‍作者 |张马也 编辑 |德新 就在前两天&#xff0c;英国AI公司Wayve宣布获得新一轮10.5亿美元融资&#xff0c;投资方为软银、英伟达和现有投资人微软&#xff0c;可以说是顶级豪华阵容。 作为一家英国公司&#xff0c;Wayve这轮融资也创造了英国AI公司有史以来最大的单笔融资…

北斗卫星在农田测量中的广泛应用

北斗卫星在农田测量中的广泛应用 随着科技的不断发展和进步&#xff0c;北斗卫星在农田测量中的应用也越来越广泛。北斗卫星系统是我国自行研制的卫星导航定位系统&#xff0c;具有全球覆盖、高精度和高可靠性的特点&#xff0c;是农田测量领域不可或缺的重要工具。 首先&…

Laravel框架使用图片处理简单教程

PHP图片处理扩展包使用 文中使用的是Laravel框架&#xff0c;更多框架扩展包请点击传送门-》更多框架集成 Intervention Image 是一个开源的 PHP 图像处理和操作 库。它提供了一个更简单也更优雅的方式来创建/编辑/组合图像,并且支持最常见的两个图像处理库 GD Library 和 Im…

静态分析-RIPS-源码解析记录-01

token流扫描重构部分&#xff0c;这一部分主要利用php的token解析api解析出来的token流&#xff0c;对其中的特定token进行删除、替换、对于特定的语法结构进行重构&#xff0c;保持php语法结构上的一致性 解析主要在lib/scanner.php中通过Tokenizer这个类来实现,也就是在main…

机器学习面试篇

如何理解机器学习数据集的概念 数据集是机器学习的基础&#xff0c;它包括了用于训练和测试模型所需的数据。数据集通常以矩阵的形式存在&#xff0c;其中每一行代表一个样本&#xff08;或实例&#xff09;&#xff0c;每一列代表一个特征&#xff08;或属性&#xff09;。…

SpringAMQP Work Queue 工作队列

消息模型: 代码模拟: 相较于之前的基础队列&#xff0c;该队列新增了消费者 不再是一个&#xff0c;所以我们通过代码模拟出两个consumer消费者。在原来的消费者类里写两个方法 其中消费者1效率高 消费者2效率低 RabbitListener(queues "simple.queue")public voi…

学习网络需要认识的各种设备

网桥&#xff08;bridge&#xff09; 网桥工作在数据链路层&#xff0c;可以把多个局域网连接起来&#xff0c;组成一个更大的局域网 以太网中&#xff0c;数据链路层地址就是mac地址&#xff0c;网桥与集线器的区别就是&#xff0c;网桥会过滤mac&#xff0c;只有目的mac地址…

draw.io 网页版二次开发(2):开始修改代码

目录 一 说明 二 打开开发环境 1. 代码调整 2. 修改访问链接 3. 注意 三 部分功能的代码汇总 1. 保存功能 2. 菜单栏折叠按钮功能 3. 顶部菜单栏 4.在顶部菜单栏中的【文件】菜单中新增选项 &#xff08;1&#xff09; 方法一&#xff1a;单独增加 &#xff08;…

calllback回调函数:同步调用,异步调用,异步回调

纯python代码的异步回调 # _*_ encoding:utf-8 _*_ import time import threading callback_value None onFlag Truedef add(a, b, num):print(f"I am the function: %s, please wait for %d" % (add.__name__, num))time.sleep(num)c a bprint("a b 1 &…

K8S搭建

文章目录 K8S搭建配置要求 安装 Kuboard-Spray加载离线资源包规划并安装集群访问集群重启Kubernetes集群Worker节点不能启动许多Pod一直Crash或不能正常访问 containerd配置网络代理 常用的 kubectl 命令&#xff1a; K8S搭建 安装高可用的Kubernetes集群 配置要求 对于 Kub…

Springboot+mybatis-plus+dynamic-datasource+继承DynamicRoutingDataSource切换数据源

Springbootmybatis-plusdynamic-datasource继承DynamicRoutingDataSource切换数据源 背景 最近公司要求支持saas&#xff0c;实现动态切换库的操作&#xff0c;默认会加载主租户的数据源&#xff0c;其他租户数据源在使用过程中自动创建加入。 解决问题 1.通过请求中设置租…

软件产品检测认证是什么?

软件产品检测认证是软件企业、系统集成商或软件商为了提高自身产品的竞争力&#xff0c;增强客户信心&#xff0c;通过第三方机构对企业的软件产品质量和可靠性进行全面测试与评估的过程。这一过程主要关注软件产品的功能、性能、安全性、可维护性等方面&#xff0c;确保软件产…

FileLink跨网文件传输医疗行业解决方案

随着医疗行业的快速发展&#xff0c;医疗机构之间的信息共享和文件传输需求日益增加。然而&#xff0c;由于网络环境的复杂性和数据安全性的要求&#xff0c;传统的文件传输方式已经无法满足医疗行业的需求。为此&#xff0c;我们推出了FileLink跨网文件传输医疗行业解决方案&a…

炫酷个人主页(源码免费)

炫酷个人主页 效果图部分代码领取源码下期更新预报 效果图 部分代码 <!DOCTYPE html> <!--哪怕是深爱之人 对我们的痛苦一无所知&#xff01;* ░░░░░░░░░░░░░░░░░░░░░░░░▄░░* ░░░░░░░░░▐█░░░░░░░░░░░▄▀▒▌░* ░…

智能座舱语音助手产品方案

一、用户调研与痛点分析 1.目标用户分析 用户画像 性别女性年龄50地域2-3线城市职业退休或退居二线教育中专、 大专、 本科财务家庭财务管理者爱好享受生活、 照顾家庭标签有闲有小钱二、产品定位与卖点提炼 购车目的 愉悦自我&#xff0c; 专属于自己的座驾&#xff1a; 家…

26-ESP32-S3 的 FLASH分区表以及 SPIFFS 文件系统 和spiffsgen.py工具

ESP32-S3 的 SPIFFS 文件系统 ESP32-S3的ROM&#xff0c;RAM&#xff0c;FLASH 存储器类型描述容量内部存储器ROM用于存储固定的程序代码和数据384KBSRAM用于存储运行时的程序数据512KBRTC SRAM在深度睡眠模式下仍然保持数据16KB外部存储器PSRAM片外用于存储运行时的程序数据…

【生信技能树】数据挖掘全流程

R包的安装&#xff0c;每次做分析的时候先运行这段代码把R包都安装好了&#xff0c;这段代码不需要任何改动&#xff0c;每次分析直接运行。 options("repos""https://mirrors.ustc.edu.cn/CRAN/") if(!require("BiocManager")) install.packag…