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://www.mzph.cn/diannao/12126.shtml

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

相关文章

IP证书签发申请

IP证书签发申请 IP证书的全称是IP SSL证书&#xff0c;其主要的作用是为IP实现https访问&#xff0c;且IP SSL证书可以完美的解决企业对于IP地址实现https加密需求。 这种类型的证书特别适合于那些没有域名只有公网IP或者不方便使用域名的企业或个人。证书允许通过特定的IP地…

Databend 开源周报第 144 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 了解 Databend …

在线制作动态图片怎么操作?一个在线制作gif的方法分享

图片在大家的生活工作中都会接触到&#xff0c;当我们想要让自己的图片更生动吸引眼球这时候就可以将几张图片制作成gif动态图。不需要下载软件&#xff0c;小白就可以在线操作&#xff0c;通过使用在线制作动态图片&#xff08;https://www.gif5.net/&#xff09;工具-GIF5工具…

服务器被后台爆破怎么处理

服务器后台遭受密码爆破攻击是网络安全中常见的威胁之一&#xff0c;这种攻击通过不断尝试不同的用户名和密码组合来破解系统登录凭证&#xff0c;一旦成功&#xff0c;攻击者便能非法访问系统资源。 本文将介绍如何识别此类攻击&#xff0c;并采取有效措施进行防御&#xff0c…

ICode国际青少年编程竞赛- Python-5级训练场-函数练习2

ICode国际青少年编程竞赛- Python-5级训练场-函数练习2 1、 def get_item(a):Spaceship.step(1)Dev.step(a)Dev.turnLeft()Dev.step(1)Spaceship.step(1)Dev.turnRight()Dev.step(-a)Spaceship.step(1) get_item(3) get_item(2) get_item(3) get_item(1) get_item(5)2、 de…

4万字一文带你看懂车载摄像头技术、市场、发展前景

1、小孔成像 在战国初期&#xff0c;我国学者墨子&#xff08;公元前468年-公元前376年&#xff09;和弟子们完成了世界上第一个小孔成像的实验&#xff0c;并记录在《墨经》中&#xff1a;“景到&#xff0c;在午有端&#xff0c;与景长。说在端。”“景。光之人&#xff0c;煦…

荆州科技局副局长乔梁莅临湖北点赋网络科技公司参观调研

近日&#xff0c;荆州科技局副局长乔梁&#xff0c;莅临湖北点赋网络科技公司进行参观调研。点赋科技总经理崔梦娇亲自陪同&#xff0c;向副局长介绍了公司的D咖智能饮品机器人经营状况和研发进展情况。 在参观过程中&#xff0c;副局长乔梁对点赋科技的创新能力和技术成果给予…

太阳能光伏发电应用过程中会用到哪些光伏组件?

随着全球对可再生能源的需求日益增加&#xff0c;太阳能光伏发电已成为一种重要的清洁能源解决方案。在太阳能光伏发电系统的运行过程中&#xff0c;光伏组件作为系统的核心部分&#xff0c;起着至关重要的作用。本文将详细介绍太阳能光伏发电应用过程中会使用到的关键光伏组件…

python输出希腊字母

有时候在绘制一些函数图像时&#xff0c;需要坐标轴和图例显示希腊字母 plt.xlabel(r’ ϵ \epsilon ϵ’)

Docker容器中的SSH免密登录

简介&#xff1a;在日常的开发和测试环境中经常需要创建和管理Docker容器。有时&#xff0c;出于调试或管理的目的&#xff0c;可能需要SSH到容器内部。本文将介绍如何创建一个Docker容器&#xff0c;它在启动时自动运行SSH服务&#xff0c;并支持免密登录。 构建支持SSH的Doc…

(八)SQL基础知识练习题(选择题)(下)#CDA学习打卡

本文整理了SQL基础知识相关的练习题&#xff0c;共133道&#xff0c;可作为CDA一级的补充习题&#xff0c;也适用于刚入门初级SQL想巩固基础的同学。来源&#xff1a;如荷学数据科学题库&#xff08;技术专项-SQL&#xff09;。暂时按照原题库顺序present&#xff0c;如有需要之…

Matlab如何批量导出多张高质量论文插图?科研效率UpUp第9期

上一期文章中&#xff0c;分享了Matlab导出高质量论文插图的方法&#xff08;Matlab如何导出高质量论文插图&#xff1f;科研效率UpUp第8期&#xff09;。 进一步&#xff0c;假如我们想要批量导出多张高质量无变形论文插图&#xff0c;该如何操作呢&#xff1f; ​也很简单&…

Java虚拟机栈

介绍 Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xff0c;简称JVM Stack&#xff09;是Java虚拟机的一个组成部分&#xff0c;它用于存储方法的局部变量、操作数栈以及动态链接和方法出口信息。JVM在执行Java程序时&#xff0c;每个线程都会有一个私有的JVM栈&…

USB2514BI-AEZG-TR USB2.0 接口转换集成电路 QFN-36参数指南

USB2514BI-AEZG-TR USB接口集成电路 USB2514BI-AEZG-TR 是一款USB接口集成电路。工作电压为3.3V&#xff0c;采用36-Pin VQFN封装。它支持USB 2.0协议&#xff0c;最大操作频率为24 MHz&#xff0c;最小操作供应电压为3V&#xff0c;最大输出电流为150mA。该器件适用于需要USB集…

VALSE 2024合合信息 | 文档解析与向量化技术加速多模态大模型训练与应用

第十四届视觉与学习青年学者研讨会&#xff08;VALSE 2024&#xff09;近期在重庆悦来国际会议中心圆满举行&#xff0c;由中国人工智能学会&#xff08;CAAI&#xff09;、中国图象图形学会&#xff08;CSIG&#xff09;、中国民族贸易促进会主办&#xff0c;重庆邮电大学承办…

AWS ECS On Fargate 监控可观测最佳实践

概述 Amazon ECS on Fargate 为用户提供了简单、高效且可靠的容器化解决方案&#xff0c;使用户能够专注于应用程序开发和运行&#xff0c;而无需担心基础设施管理的复杂性。与其同时&#xff0c;用户需要实时了解在该环境中应用程序运行的性能、可用性、健康状况和资源使用情…

【BUUCTF】Crypto_RSA(铜锁/openssl使用系列)

【BUUCTF】Crypto_RSA&#xff08;铜锁/openssl使用系列&#xff09; 1、题目 在一次RSA密钥对生成中&#xff0c;假设p473398607161&#xff0c;q4511491&#xff0c;e17 求解出d作为flga提交 2、解析 RSA加密过程&#xff1a; 1&#xff09;选择素数&#xff1a;选择两个不…

rabbitmq交换机,死信队列的简单例子

假设我们有一个场景&#xff0c;生产者有消息发到某个直连交换机&#xff0c;这个交换机上有两个队列分别存储两种类型的消息&#xff0c;但是与这两个队列相连的消费者太不争气了&#xff0c;处理消息有点慢&#xff0c;我们想5秒钟这个消息在队列中还没有被消费的话&#xff…

【MIT6.S081】Lab7: Multithreading(详细解答版)

实验内容网址:https://xv6.dgs.zone/labs/requirements/lab7.html 本实验的代码分支:https://gitee.com/dragonlalala/xv6-labs-2020/tree/thread2/ Uthread: switching between threads 关键点:线程切换、swtch 思路: 本实验完成的任务为用户级线程系统设计上下文切换机制…

SGPM02陀螺仪模块通过惯性导航助力AGV小车的发展

之前我们介绍过SGPM01系列陀螺仪模块在智能泳池清洁机器人导航的方案(SGPM01)。这款惯性导航模块收到了许多企业的欢迎。由此&#xff0c;爱普生推出了SGPM02系列陀螺仪模块通过惯性导航&#xff0c;助力AGV小车的发展。 AGV是一种用于运输材料的无人驾驶车辆&#xff0c;并且A…