探索C语言中的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时,务必考虑到道德和法律问题。合法的安全研究和渗透测试是为了改善系统安全性,而非进行恶意攻击。遵循相关法规和道德准则是安全研究的基本原则。
探索C语言中的Shellcode从提取到执行的更多相关文章
- 浅谈Java语言中try{}catch{}和finally{}的执行顺序问题
浅谈Java语言中try{}catch{}和finally{}的执行顺序问题 2019-04-06 PM 13:41:46 1. 不管有没有出现异常,finally块中代码都会执行: 2. 当t ...
- C语言中,头文件和源文件的关系(转)
简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...
- C语言中.h和.c文件解析(很精彩)
C语言中.h和.c文件解析(很精彩) 简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析 ...
- C语言中.h和.c文件解析
整理自C语言中.h和.c文件解析(很精彩) Part.1(林锐<高质量C/C++编程>) 通过头文件来调用库功能.在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的 ...
- 转-C语言中.h和.c文件解析
C语言中.h和.c文件解析(很精彩) 简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词 ...
- 关于C语言中printf函数“输出歧视”的问题
目录 关于C语言中printf函数"输出歧视"的问题 问题描述 探索问题原因 另一种研究方法 问题结论 关于C语言中printf函数"输出歧视"的问题 问题描述 ...
- C语言中.h和.c文件解析(转载)
转载:http://www.cnblogs.com/laojie4321/archive/2012/03/30/2425015.html 简单的说其实要理解C文件与头文件(即.h)有什么不同之处, ...
- c语言中"->"和"."的区别
对于c语言中"->"和"."的区别总结如下: 1.A.B则A为对象或者结构体: 2.A->B则A为指针,->是成员提取,A->B是提取A ...
- C 语言中 setjmp 和 longjmp
在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...
- c语言中的scanf在java中应该怎么表达,Scanner类。
1 java是面向对象的语言 它没有像C语言中的scanf()函数,但是它的类库中有含有scanf功能的函数 2 java.util包下有Scanner类 Scanner类的功能与scanf类似 3 ...
随机推荐
- KB21N、KB24N作业分配与冲销
一.KB21N 调用BAPI:BAPI_ACC_ACTIVITY_ALLOC_POST 经测试,分配订单时行项目一次性最多传332条数据 "------------------------- ...
- SpringBoot 项目实战 | 瑞吉外卖 Day06
该系列将记录一份完整的实战项目的完成过程,该篇属于第六天 案例来自B站黑马程序员Java项目实战<瑞吉外卖>,请结合课程资料阅读以下内容 该篇我们将完成以下内容: 用户地址簿相关功能 菜品 ...
- #1198:Farm Irrigation(DFS + 并查集)
Farm Irrigation **Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- SD-Host控制器设计架构
SD Host功能列表 SD Host挂接在SoC中,与外部的SD card进行交互 有控制寄存器和状态寄存器,SoC往往有CPU,通过CPU进行配置寄存器,有些SoC没有CPU,需要使用I2C或者S ...
- java - 正确关闭流
package stream; import java.io.*; public class FileReaderTest { public static void main(String[] arg ...
- Laravel - 虚拟主机引入静态资源
一. 注意: 引用的静态文件要放在根目录,不要放在assets目录下 二. 引入方法 1. 模板中引入 css <link rel="stylesheet" hr ...
- [转帖]DevOps & CI/CD 常见面试题汇总
https://www.cnblogs.com/Dev0ps/p/15123168.html 什么是 DevOps答:用最简单的术语来说,DevOps 是产品开发过程中开发(Dev)和运营(Ops) ...
- [转帖]Linux的缓存内存(cache memory)
PS:为什么Linux系统没运行多少程序,显示的可用内存这么少?其实Linux与Win的内存管理不同,会尽量缓存内存以提高读写性能,通常叫做Cache Memory. 为什么Linux系统没运行多少程 ...
- [转帖]061、监控指标之TiKV
资源相关 Grafana监控 TiKV-Details -> Cluster - Store Size / Available Size Grafana监控 TiKV-Details -> ...
- lightning 导入数据库表的操作步骤
lightning 导入数据库表的操作步骤 TiDB数据库备份恢复的方式与方法 1. mysqldumper 以及 mysql 导入 2. select into outfile 以及 load da ...