首页 > 系统相关 >re | 通过C语言编写shellcode(vc6)

re | 通过C语言编写shellcode(vc6)

时间:2023-12-23 22:55:19浏览次数:28  
标签:index dwKernel32Base pLdrDataEntry LIST C语言 char re vc6 ENTRY

re | 通过C语言编写shellcode(vc6)

接上一篇博客:https://www.cnblogs.com/Mz1-rc/p/17923224.html

对上文中代码进行修改,不使用全局字符串,不使用外部函数调用,关闭/GZ编译选项(栈检查):

#include <stdio.h>
#include <windows.h>

typedef int (WINAPI* PMESSAGEBOXA)(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption, UINT uType);
typedef FARPROC (WINAPI* PGETPROCADDRESS)(HMODULE hModule,LPCSTR lpProcName);
typedef HMODULE (WINAPI* PLOADLIBRARY)(LPCTSTR lpFileName);
/*
typedef struct _LIST_ENTRY {
   struct _LIST_ENTRY *Flink;
   struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
*/

typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;                  // 3个双向链表
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID      DllBase;
    PVOID      EntryPoint;
    UINT    SizeOfImage;               // 这里32位的就是UINT 64位是UINT64
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;     // 查找这个
	//...
}LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

void shellcode(){
	// 准备字符串备用
	// wchar_t wsKernel32Dll[] = L"kernel32.dll";
	char wsKernel32Dll[] = {'K', 0, 'E', 0, 'R', 0, 'N', 0, 'E', 0, 'L', 0, '3', 0, '2', 0, '.', 0, 'D', 0, 'L', 0, 'L', 0, 0, 0};
	char sUser32Dll[] = {'U', 'S', 'E', 'R', '3', '2', '.', 'd', 'l', 'l', 0};
	char sGetProcAddr[] = {'G', 'e', 't', 'P', 'r', 'o', 'c', 'A', 'd', 'd', 'r', 'e', 's', 's', 0};
	char sLoadLibraryA[] = {'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'A', 0};
	char sMessageBoxA[] = {'M', 'e', 's', 's', 'a', 'g', 'e', 'B', 'o', 'x', 'A', 0};

	// 通过fs:[0x30]查找PEB 找到3个链表 找到K32.dll
	/*
	_PEB_LDR_DATA
	[0] Length
	[4] Initialized
	[8] SsHandle
	[c] InLoadOrderModuleList : _LIST_ENTRY
	[14] InMemoryOrderModuleList : _LIST_ENTRY
	[1c] InInitializationOrderModuleList : _LIST_ENTRY
	...

	*/
	DWORD pBeg = 0;
	DWORD pPLD = 0;
	PLIST_ENTRY pInLoadOrderModuleList = 0;
	__asm{
		pushad
		mov eax, fs:[0x30]        ; PEB
		mov eax, [eax+0x0c]       ; PEB->Ldr
		add eax, 0x0c             ; _PEB_LDR_DATA->InLoadOrderModuleList
		lea ebx, dword ptr [pInLoadOrderModuleList] ; 获取InLoadOrderModuleList的地址保存在变量中
		mov [ebx], eax;
		popad
	}
	//printf("InLoadOrderModuleList: %p %p \n",pInLoadOrderModuleList->Flink, pInLoadOrderModuleList->Blink);
	// 拿到第一个LDR_DATA_TABLE_ENTRY节点的地址
	PLDR_DATA_TABLE_ENTRY pFirstLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)pInLoadOrderModuleList->Flink;
	// 循环遍历所有的模块 查找kernel32.dll
	DWORD dwKernel32Base = 0;
	PLDR_DATA_TABLE_ENTRY pLdrDataEntry = pFirstLdrDataEntry;
	while(1){
		//printf("[%p] %p %p \n", pLdrDataEntry, pLdrDataEntry->InLoadOrderLinks.Flink, pLdrDataEntry->InLoadOrderLinks.Blink);
		//printf("    [%S(%p)] %S \n", pLdrDataEntry->BaseDllName.Buffer, pLdrDataEntry->DllBase, pLdrDataEntry->FullDllName.Buffer);
		if (pLdrDataEntry->InLoadOrderLinks.Flink == (PLIST_ENTRY)pFirstLdrDataEntry){
			break;
		}
		// 判断是不是kernel32.dll
		/*
		if(wcsicmp(pLdrDataEntry->BaseDllName.Buffer, (wchar_t*)wsKernel32Dll) == 0){
			//printf("~~~~~~ find it! ~~~~~~~\n");
			dwKernel32Base = (DWORD)pLdrDataEntry->DllBase;
		}
		*/
		// 手动编写wcscmp
		wchar_t* wtmp = (wchar_t*)(pLdrDataEntry->BaseDllName.Buffer);
		int index = 0;
		int length = 0;
		while(((wchar_t*)wsKernel32Dll)[index] != 0){   // 计算长度
			index ++;
		}
		length = index;
		for (index = 0; index < length; index ++){      // 对比
			if (((wchar_t*)wsKernel32Dll)[index] != wtmp[index]){
				break;
			}
		}
		if (index == length){   // 找到了
			//puts("found");       // 找到kernel32.dll
			dwKernel32Base = (DWORD)pLdrDataEntry->DllBase;
		}

		pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)pLdrDataEntry->InLoadOrderLinks.Flink;
	}
	//printf("kernel32.dll base: %p \n", dwKernel32Base);  // 拿到kernel32.dll基址
	// 通过导出表查找LoadLibrary
	PIMAGE_DOS_HEADER pIDH = (PIMAGE_DOS_HEADER)dwKernel32Base;
	PIMAGE_NT_HEADERS pINHS = (PIMAGE_NT_HEADERS)(dwKernel32Base+pIDH->e_lfanew);
	PIMAGE_EXPORT_DIRECTORY pIED = (PIMAGE_EXPORT_DIRECTORY)(dwKernel32Base + pINHS->OptionalHeader.DataDirectory[0].VirtualAddress);
	DWORD* pAddressOfFunctions = (DWORD*)(dwKernel32Base + pIED->AddressOfFunctions);
	DWORD* pAddressOfNames = (DWORD*)(dwKernel32Base + pIED->AddressOfNames);
	WORD* pAddressOfNameOrdinals = (WORD*)(dwKernel32Base + pIED->AddressOfNameOrdinals);
	int i = 0;
	while(1){
		// printf("[%d] %s {%d} \n", i, dwKernel32Base+pAddressOfNames[i], pAddressOfNameOrdinals[i]);
		/*
		if (strcmp(sGetProcAddr, (char*)(dwKernel32Base + pAddressOfNames[i]))==0){
			//puts("found");       // 找到对应在序号表的第i个位置
			break;
		}
		*/
		// 手动编写strcmp
		char* tmp = (char*)(dwKernel32Base + pAddressOfNames[i]);
		int index = 0;
		int length = 0;
		while(sGetProcAddr[index] != '\0'){   // 计算长度
			index ++;
		}
		length = index;
		for (index = 0; index < length; index ++){      // 对比
			if (sGetProcAddr[index] != tmp[index]){
				break;
			}
		}
		if (index == length){   // 找到了
			// puts("found");       // 找到对应在序号表的第i个位置
			break;
		}
		// 下一个条目
		i ++;
	}
	i = pAddressOfNameOrdinals[i];
	//printf("i=%d in AddressOfFunctions = 0x%p \n", i, dwKernel32Base + pAddressOfFunctions[i]);
	PGETPROCADDRESS pGetProcAddress = (PGETPROCADDRESS)(dwKernel32Base + pAddressOfFunctions[i]);
	PLOADLIBRARY pLoadLibrary = (PLOADLIBRARY)pGetProcAddress((HMODULE)dwKernel32Base, sLoadLibraryA);
	//printf("loadlibrary: 0x%p \n", pLoadLibrary);
	HMODULE hUser32DLL = pLoadLibrary(sUser32Dll);
	PMESSAGEBOXA pMessageBoxA = (PMESSAGEBOXA)pGetProcAddress(hUser32DLL, sMessageBoxA);
	char sHeader[] = {'M', 'z', '1', 0};
	char sText[] = {'i', 'n', 'j', 'e', 'c', 't', 'e', 'd', 0};
	pMessageBoxA(0,sText ,sHeader,0);
}

int main(){
	shellcode();

	return 0;
}

然后提取shellcode,可以在任何位置独立执行:

558BEC81EC00010000535657C645E44BC645E500C645E645C645E700C645E852C645E900C645EA4EC645EB00C645EC45C645ED00C645EE4CC645EF00C645F033C645F100C645F232C645F300C645F42EC645F500C645F644C645F700C645F84CC645F900C645FA4CC645FB00C645FC00C645FD00C645D855C645D953C645DA45C645DB52C645DC33C645DD32C645DE2EC645DF64C645E06CC645E16CC645E200C645C847C645C965C645CA74C645CB50C645CC72C645CD6FC645CE63C645CF41C645D064C645D164C645D272C645D365C645D473C645D573C645D600C645B84CC645B96FC645BA61C645BB64C645BC4CC645BD69C645BE62C645BF72C645C061C645C172C645C279C645C341C645C400C645AC4DC645AD65C645AE73C645AF73C645B061C645B167C645B265C645B342C645B46FC645B578C645B641C645B700C745A800000000C745A400000000C745A0000000006064A1300000008B400C83C00C8D9DA0FFFFFF8903618B45A08B08894D9CC74598000000008B559C895594B80100000085C00F849B0000008B4D948B113B559C7505E98C0000008B45948B4830894D90C7458C00000000C74588000000008B558C33C0668B4455E485C0740B8B4D8C83C101894D8CEBE78B558C895588C7458C00000000EB098B458C83C00189458C8B4D8C3B4D887D1E8B558C33C0668B4455E48B4D8C8B559033F6668B344A3BC67402EB02EBD18B458C3B458875098B4D948B51188955988B45948B08894D94E958FFFFFF8B55988955848B45848B4D9803483C894D808B55808B459803427889857CFFFFFF8B8D7CFFFFFF8B559803511C899578FFFFFF8B857CFFFFFF8B4D98034820898D74FFFFFF8B957CFFFFFF8B4598034224898570FFFFFFC7856CFFFFFF00000000B90100000085C90F84C70000008B956CFFFFFF8B8574FFFFFF8B4D98030C90898D68FFFFFFC78564FFFFFF00000000C78560FFFFFF000000008B9564FFFFFF0FBE4415C885C074118B8D64FFFFFF83C101898D64FFFFFFEBE08B9564FFFFFF899560FFFFFFC78564FFFFFF00000000EB0F8B8564FFFFFF83C001898564FFFFFF8B8D64FFFFFF3B8D60FFFFFF7D228B9564FFFFFF0FBE4415C88B8D68FFFFFF038D64FFFFFF0FBE113BC27402EB02EBC18B8564FFFFFF3B8560FFFFFF7502EB148B8D6CFFFFFF83C101898D6CFFFFFFE92CFFFFFF8B956CFFFFFF8B8570FFFFFF33C9668B0C50898D6CFFFFFF8B956CFFFFFF8B8578FFFFFF8B4D98030C90898D5CFFFFFF8D55B8528B459850FF955CFFFFFF898558FFFFFF8D4DD851FF9558FFFFFF898554FFFFFF8D55AC528B8554FFFFFF50FF955CFFFFFF898550FFFFFFC6854CFFFFFF4DC6854DFFFFFF7AC6854EFFFFFF31C6854FFFFFFF00C68540FFFFFF69C68541FFFFFF6EC68542FFFFFF6AC68543FFFFFF65C68544FFFFFF63C68545FFFFFF74C68546FFFFFF65C68547FFFFFF64C68548FFFFFF006A008D8D4CFFFFFF518D9540FFFFFF526A00FF9550FFFFFF5F5E5B8BE55DC3CCCCCCCCCCCCCCCCCCCCCCCCCCCC

爽!!!!!!!!!!!!!!!!!!!!!
image

标签:index,dwKernel32Base,pLdrDataEntry,LIST,C语言,char,re,vc6,ENTRY
From: https://www.cnblogs.com/Mz1-rc/p/17923792.html

相关文章

  • PTA|C语言|指针
    计算最长的字符串长度本题要求实现一个函数,用于计算有n个元素的指针数组s中最长的字符串的长度。函数接口定义:intmax_len(char*s[],intn);其中n个字符串存储在s[]中,函数max_len应返回其中最长字符串的长度。裁判测试程序样例:#include<stdio.h>#include<string.h>#include......
  • 无涯教程-PostgreSQL - 环境设置
    要开始了解PostgreSQL基础,首先让无涯教程安装PostgreSQL,本章说明有关在Linux,Windows和MacOS平台上安装PostgreSQL的信息。在Linux/Unix上安装请按照给定的步骤在Linux机器上安装PostgreSQL,在继续安装之前,请确保您以root身份登录。从中选择所需的PostgreSQL版本号,并尽可能精......
  • C语言一些小细节
    intvalue=1;intarr[2]={value,2};//C语言错,C++对intarr1[2];arr1[0]=1;//C语言错,C++错inta;a=10;//C语言错,C++错intmain(){intnum;staticintarr[2]={num,2};//C语言错,C++错intnum1=10;staticintarr1[2]={num,2};//C语言错,C++错retu......
  • FLAC: Federated Learning with Autoencoder Compression and Convergence Guarantee-
    目的:减少通信量(成本),例如VGGNet架构具有大约1.38亿个参数(4264Mb)方法:具有自动编码器压缩(AutoencoderCompression)且具有收敛保证(ConvergenceGuarantee);利用冗余信息(theredundantinformation)和FL的迭代纠错能力(iterativeerror-correctingcapabilityofFL)来压缩client的模型,......
  • Redis 哨兵集群搭建并使用 RedisTemplate 实现读写分离
    上篇博客介绍的Redis主从集群搭建,有一个缺点就是master和slave的角色是固定的,不会发生变化。一旦master节点宕机,那么集群就只能提供读服务,无法提供写服务。本篇博客介绍Redis哨兵集群的搭建,可以监控Redis集群的master和slave节点,最重要的是一旦master宕机,哨兵集......
  • Eureka Server 自我保护机制
    https://blog.csdn.net/u012410733/article/details/112303048下面是官方提供的Eureka架构图: 1、什么是自我保护机制默认情况下,如果EurekaServer在一定时间内(默认90秒,其实不止90秒)没有接收到某个微服务实例的心跳,EurekaServer将会移除该实例。但是当网络分区故障发生......
  • CRC-Aided Sparse Regression Codes for Unsourced Random Access
    一、摘要随记仅用于个人对论文的分析、初步复现。1.1文件夹介绍随机包含了一篇论文的仿真结果的源代码,该论文的标题是"CRC-aidedSpareRegressionCodesforUnsourcedRandomAccess"。源代码CRC-aided_SPARCs_for_URA-main,一共包括三个文件夹:"CRC-BMSTcodesforst......
  • CF1055F Tree and XOR
    这道题代码虽然比较短,但花了我整整一天才过,太菜了这是CF241B的加强版,但是有点不同,因为CF241B后半部分求前\(k\)大的和没法优化了,而这道题能把前面的求第\(k\)小时间复杂度优化到单log,但是需要注意这道题开trie完全开不下,所以肯定没法trie上二分做到单log对于某些......
  • C语言实现面向对象的方法详解
    结构体替代类使用结构体来封装变量和函数,即可实现类似对象的功能。其中,结构体包含变量和函数指针,变量用于存储成员变量的值,函数指针用于实现成员函数的功能。而每个对象的变量是独立的,因此可以使用这种方法实现类似对象的功能。下面是一个例子,以封装一个“人”的结构体为例:typ......
  • 策略模式(Strategy Pattern) .Net Core实现
    在策略模式(StrategyPattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象。策略对象改变context对象的执行算法。意图:定义一系列的算法,把它们一个个......