首页 > 系统相关 >探索C语言中的Shellcode从提取到执行

探索C语言中的Shellcode从提取到执行

时间:2023-12-06 19:57:45浏览次数:29  
标签:fp 提取 unsigned Len C语言 char newBuffer Shellcode

ShellCode是一种独立于应用程序的机器代码,通常用于实现特定任务,如执行远程命令、注入恶意软件或利用系统漏洞。在网络安全领域,研究Shellcode是理解恶意软件和提高系统安全性的关键一环。本文将深入探讨如何在C语言中提取Shellcode,并通过XOR加密技术增加其混淆程度。最后,我们将演示如何将Shellcode写入文件并在内存中执行。

第一步:提取Shellcode

提取ShellCode的主要方法是通过Visual C++编译器的内嵌汇编功能,通过内嵌一条offset特殊的汇编伪指令分别得到内嵌汇编的开始和结尾,然后再利用灵活的内存拷贝命令即可对编译后的汇编指令进行动态的提取工作,当提取后直接将其输出为二进制格式即可,这里提供了两种提取模式,第一种是直接提取二进制机器码此类功能可以直接被运行,第二种则是提取unicode格式,通过向ShellCodeStart-ShellCodeEnd提取代码如下所示。

#include <stdio.h>
#include <Windows.h>

int main(int argc, char* argv[])
{
	DWORD Start, End, Len;
	goto GetShellCode;
	__asm
	{
	ShellCodeStart:
		xor eax, eax
			xor ebx, ebx
			xor ecx, ecx
			xor edx, edx
			int 3
	ShellCodeEnd:
	}

GetShellCode:
	__asm
	{
		mov Start, offset ShellCodeStart
			mov End, offset ShellCodeEnd
	}

	Len = End - Start;
	unsigned char* newBuffer = new unsigned char[Len + 1024];

	memset(newBuffer, 0, Len + 1024);
	memcpy(newBuffer, (unsigned char*)Start, Len);

	// 直接写出二进制
	FILE* fp_bin = fopen("d://shellcode.bin", "wb+");
	fwrite(newBuffer, Len, 1, fp_bin);
	_fcloseall();

	// 写出Unicode格式ShellCode
	FILE *fp_uncode = fopen("c://un_ShellCode.txt", "wb+");
	for (int x = 0; x < Len; x++)
	{
		fprintf(fp_uncode, "%%u%02x%02x", newBuffer[x + 1], newBuffer[x]);
	}
	_fcloseall();
	return 0;
}

第二步:XOR加密Shellcode

为了增加Shellcode的混淆性,我们引入异或(XOR)加密技术。以下是对提取的Shellcode进行异或加密的C代码:

unsigned char ch;
for (int x = 0; x < Len; x++)
{
  ch = ((unsigned char*)newBuffer)[x];
  ch = ch ^ 10;  // 异或加密
  newBuffer[x] = ch;
}

在这里,我们对Shellcode中的每个字节都执行异或运算,以提高其抵抗分析的能力。

#include <stdio.h>
#include <Windows.h>

int main(int argc, char* argv[])
{
  DWORD Start, End, Len;
  goto GetShellCode;
  __asm
  {
  ShellCodeStart:
    xor eax, eax
      xor ebx, ebx
      xor ecx, ecx
      xor edx, edx
      int 3
      ShellCodeEnd :
  }

GetShellCode:
  __asm
  {
    mov Start, offset ShellCodeStart
    mov End, offset ShellCodeEnd
  }

  Len = End - Start;
  unsigned char* newBuffer = new unsigned char[Len + 1024];

  memset(newBuffer, 0, Len + 1024);
  memcpy(newBuffer, (unsigned char*)Start, Len);

  // 使用异或加密ShellCode
  unsigned char ch;
  for (int x = 0; x < Len; x++)
  {
    ch = ((unsigned char*)newBuffer)[x];
    ch = ch ^ 10;
    newBuffer[x] = ch;
  }

  // 将ShellCode写出到文件
  FILE* fp = fopen("d://shellcode.txt", "wb+");
  fwrite("unsigned char Buf[] = {", 23, 1, fp);
  for (int x = 0; x < Len; x++)
  {
    if (x % 16 == 0)
      fwrite("\r\n", 2, 1, fp);
    fprintf(fp, "0x%02x,", newBuffer[x]);
  }
  fwrite("\n};", 3, 1, fp);
  _fcloseall();
  return 0;
}

第三步:执行Shellcode

最后,我们将动态读取Shellcode并在内存中执行它。以下是实现这一步的C代码:

#include <stdio.h>
#include <Windows.h>

int main(int argc, char * argv[])
{
  HANDLE fp;
  unsigned char * fBuffer;
  DWORD fSize, dwSize;

  fp = CreateFile(L"d://shellcode.bin", GENERIC_READ, FILE_SHARE_READ, NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  fSize = GetFileSize(fp, 0);

  fBuffer = (unsigned char *)VirtualAlloc(NULL, fSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  ReadFile(fp, fBuffer, fSize, &dwSize, 0);
  CloseHandle(fp);

  __asm
  {
    mov eax,fBuffer
    push eax
    ret
    int 3
  }
  return 0;
}

此段代码打开文件,将Shellcode读入内存,然后通过汇编代码执行它。这是一个基本的Shellcode执行例子,实际上,执行Shellcode的方式取决于应用场景和操作系统。

总结

通过这个简单的实例,我们深入探讨了从C语言中提取Shellcode的过程,介绍了XOR加密技术以提高Shellcode的混淆性,最后演示了如何在内存中执行Shellcode。理解这些概念对于防范和分析恶意软件至关重要,同时也为安全研究提供了有趣而深刻的领域。

额外考虑因素

在使用Shellcode时,务必考虑到道德和法律问题。合法的安全研究和渗透测试是为了改善系统安全性,而非进行恶意攻击。遵循相关法规和道德准则是安全研究的基本原则。

标签:fp,提取,unsigned,Len,C语言,char,newBuffer,Shellcode
From: https://www.cnblogs.com/LyShark/p/17880377.html

相关文章

  • C语言三维智能PACS系统源码,医学影像采集系统
    三维智能PACS系统源码,医学影像采集传输系统源码PACS系统以大型关系型数据库作为数据和图像的存储管理工具,以医疗影像的采集、传输、存储和诊断为核心,集影像采集传输与存储管理、影像诊断查询与报告管理、综合信息管理等综合应用于一体的综合应用系统。日常产生的各种医学影像通过国......
  • C语言中的struct结构体、union联合体、enum枚举和typedef
    C语言中的struct结构体、union联合体、enum枚举和typedef结构体struct结构体是C编程中另一种用户自定义的可用的数据类型,它允许存储不同类型的数据项。结构体中的数据成员可以是基本数据类型(如int、float、char等),也可以是其他结构体类型、指针类型等。关键字:structstruct......
  • 《初学C语言第16天》
    //作业二刷+详情解释(已吃透)//4.1--X图形(switch语句方法)(此方法较麻烦且可读性低,不建议)//#define_CRT_SECURE_NO_WARNINGS//#include<stdio.h>//voidA(inta)//{// inti,j;// for(i=0;i<a;i++)// {// for(j=0;j<a;j++)// {//  if(i==j||i+......
  • 冒泡排序法(C语言)
    #include<stdio.h>intmain(){ inti,j; intarr[10]={4,1,3,2,5,8,9,7,6,1};//定义一个数组总元素个数为10 for(i=0;i<9;i++){//外层循环循环次数为数组总元素减一 for(j=0;j<9-i;j++){//内层循环为从一个数开始与右邻进行比较并排序,  if(arr[j]>ar......
  • C语言中的基本数据类型及其格式化输出
    C语言中的基本数据类型及其格式化输出基本数据类型从下图可以看出,C语言中的基本数据类型包括了整型(int)、字符型(char)、浮点型(float)和双精度浮点型(double)。在声明变量时,不同数据类型都会分配不同的存储空间,而且还跟操作系统有关。char//有符号字符型,1个字节u......
  • 数据结构常见存储方式c语言
     图---邻接矩阵/*图的邻接矩阵存储表示法*///用两个数组分别存储顶点表和邻接矩阵#defineMaxInt32767//表示极大值,即无穷#defineMVNum100//最大顶点数typedefcharVerTexType;//假设顶点的数据类型为字符型typedefintArcType;//假设边的权值类型为整型......
  • 【C语言调用Python】Py_Finalize() 时报 GC 崩溃错误。
    Py_Finalize()时报GC崩溃错误。记一次有趣的报错随笔。报错现场在使用如下的报错代码时,在释放阶段调用Py_Finalize(),报如下Assert崩溃。原因结论在调用函数逻辑里的Exit0中,对变量pModuleDict和pClass进行了手动释放,引用计数-1(宏KLP_RELEASE),这两个变量是借用的引用变量,不......
  • 【C语言总集篇】操作符篇——从不会到会的过程
    前言大家好,很高兴又和大家见面了!现在我们以及结束了数组与函数知识板块的学习,今天我们将进入下一个板块——操作符板块的学习,下面开始介绍我们今天的内容吧。一、操作符分类算术操作符移位操作符位操作符赋值操作符单目操作符关系操作符逻辑操作符条件操作符逗号表达式下标引用、函......
  • 《初学C语言第15天》
    //////————————————————————进阶版////数据在内存中的存储////1.数据类型的介绍//#include<stdio.h>//intmain()//{// inta=10;//4字节// floatf=10.0;//4字节// shortintb=10;// printf("%p\n",f);// return0;//}////整型类型//char......
  • 【C语言基础】float、double 浮点数类型的四舍五入问题
    简短不看版:C语言中,不能进行doublea==doubleb 这样的运算。另外,printf(".1f",&double)的时候,数据输出不同时候,可能会不一样。根本问题时float类型或者double类型的浮点数在计算机中不能精确储存。              单精度浮点型(float)存储方式比如,若我们希......