第14节 第二种shellcode编写实战(3)

我最近在做一个关于shellcode入门和开发的专题课👩🏻‍💻,主要面向对网络安全技术感兴趣的小伙伴。这是视频版内容对应的文字版材料,内容里面的每一个环境我都亲自测试实操过的记录,有需要的小伙伴可以参考。

我的个人主页:https://imbyter.com

在第二种shellcode编写实战(1)中实现了以C语言或C++类的方式完成多文件shellcode编写的框架,在第二种shellcode编写实战(2)中实现了以CAPI类处理函数动态调用的方式,使shellcode结构更加清晰。接下来处理最后一个问题,解决双引号字符串使用的问题。

有两种方式供选择:

  1. 我们可以直接以类似char szData = {'x','x','x',0};的方式去处理使用每一个字符串,优点是每个字符串的使用可控,缺点是编写比较麻烦。
  2. 可以使用ADVobfuscator开源项目,自动化处理所有用到的字符串,优点是编写简单,效率高。

在前面的编程中,我们都是使用的第一种方式。接下来我们尝试使用ADVobfuscator来提高shellcode字符换处理效率。

ADVobfuscator是Github中一个能够实现自动化处理字符串的开源项目,地址为:GitHub - andrivet/ADVobfuscator: Obfuscation library based on C++11/14 and metaprogramming

该项目通过提供的两个字符串混淆加密接口,能够非常简单高效的对指定的字符串进行加密混淆,使用方便,处理效果好。经实测具备以下几个特点:

  1. 默认仅在发布版(Release)编译时开启字符串混淆,调试版(Debug)不会启用;
  2. 对全局字符串和局部字符串均能有效处理;
  3. 每次编译均使用随机密钥对字符串进行加密;(即对同一个项目连续编译两次,每次生成的PE中字符串的加密结果都不相同)
  4. 正常情况下使用的明文字符串编译后存放在PE结构中的数据段中,此代码处理过的字符串会被加密存放在代码段中,更加隐蔽;

我们在原版的基础上做了适当的整合,使用时只需要包含一个obf.h文件即可:

obf.h:

#pragma once// reference https://github.com/andrivet/ADVobfuscator#if defined(_MSC_VER)
#define ALWAYS_INLINE __forceinline
#else
#define ALWAYS_INLINE __attribute__((always_inline))
#endif#include <iomanip>
#include <iostream>// std::index_sequence will be available with C++14 (C++1y). For the moment, implement a (very) simplified and partial version. You can find more complete versions on the Internet
// MakeIndex<N>::type generates Indexes<0, 1, 2, 3, ..., N>namespace andrivet {namespace ADVobfuscator {template<int... I>struct Indexes { using type = Indexes<I..., sizeof...(I)>; };template<int N>struct Make_Indexes { using type = typename Make_Indexes<N - 1>::type::type; };template<>struct Make_Indexes<0> { using type = Indexes<>; };}
}// Very simple compile-time random numbers generator.// For a more complete and sophisticated example, see:
// http://www.researchgate.net/profile/Zalan_Szgyi/publication/259005783_Random_number_generator_for_C_template_metaprograms/file/e0b49529b48272c5a6.pdf#include <random>namespace andrivet {namespace ADVobfuscator {namespace{// I use current (compile time) as a seedconstexpr char time[] = __TIME__; // __TIME__ has the following format: hh:mm:ss in 24-hour time// Convert time string (hh:mm:ss) into a numberconstexpr int DigitToInt(char c) { return c - '0'; }const int seed = DigitToInt(time[7]) +DigitToInt(time[6]) * 10 +DigitToInt(time[4]) * 60 +DigitToInt(time[3]) * 600 +DigitToInt(time[1]) * 3600 +DigitToInt(time[0]) * 36000;}// 1988, Stephen Park and Keith Miller// "Random Number Generators: Good Ones Are Hard To Find", considered as "minimal standard"// Park-Miller 31 bit pseudo-random number generator, implemented with G. Carta's optimisation:// with 32-bit math and without divisiontemplate<int N>struct MetaRandomGenerator{private:static constexpr unsigned a = 16807;        // 7^5static constexpr unsigned m = 2147483647;   // 2^31 - 1static constexpr unsigned s = MetaRandomGenerator<N - 1>::value;static constexpr unsigned lo = a * (s & 0xFFFF);                // Multiply lower 16 bits by 16807static constexpr unsigned hi = a * (s >> 16);                   // Multiply higher 16 bits by 16807static constexpr unsigned lo2 = lo + ((hi & 0x7FFF) << 16);     // Combine lower 15 bits of hi with lo's upper bitsstatic constexpr unsigned hi2 = hi >> 15;                       // Discard lower 15 bits of histatic constexpr unsigned lo3 = lo2 + hi;public:static constexpr unsigned max = m;static constexpr unsigned value = lo3 > m ? lo3 - m : lo3;};template<>struct MetaRandomGenerator<0>{static constexpr unsigned value = seed;};// Note: A bias is introduced by the modulo operation.// However, I do belive it is neglictable in this case (M is far lower than 2^31 - 1)template<int N, int M>struct MetaRandom{static const int value = MetaRandomGenerator<N + 1>::value % M;};}
}namespace andrivet {namespace ADVobfuscator {struct HexChar{unsigned char c_;unsigned width_;HexChar(unsigned char c, unsigned width) : c_{ c }, width_{ width } {}};inline std::ostream& operator<<(std::ostream& o, const HexChar& c){return (o << std::setw(c.width_) << std::setfill('0') << std::hex << (int)c.c_ << std::dec);}inline HexChar hex(char c, int w = 2){return HexChar(c, w);}}
}namespace andrivet {namespace ADVobfuscator {// Represents an obfuscated string, parametrized with an alrorithm number N, a list of indexes Indexes and a key Keytemplate<int N, char Key, typename Indexes>struct MetaString;// Partial specialization with a list of indexes I, a key K and algorithm N = 0// Each character is encrypted (XOR) with the same keytemplate<char K, int... I>struct MetaString<0, K, Indexes<I...>>{// Constructor. Evaluated at compile time.constexpr ALWAYS_INLINE MetaString(const char* str): key_{ K }, buffer_{ encrypt(str[I], K)... } { }// Runtime decryption. Most of the time, inlinedinline const char* decrypt(){for (size_t i = 0; i < sizeof...(I); ++i)buffer_[i] = decrypt(buffer_[i]);buffer_[sizeof...(I)] = 0;//LOG("--- Implementation #" << 0 << " with key 0x" << hex(key_));return const_cast<const char*>(buffer_);}private:// Encrypt / decrypt a character of the original string with the keyconstexpr char key() const { return key_; }constexpr char ALWAYS_INLINE encrypt(char c, int k) const { return c ^ k; }constexpr char decrypt(char c) const { return encrypt(c, key()); }volatile int key_; // key. "volatile" is important to avoid uncontrolled over-optimization by the compilervolatile char buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte};// Partial specialization with a list of indexes I, a key K and algorithm N = 1// Each character is encrypted (XOR) with an incremented key.template<char K, int... I>struct MetaString<1, K, Indexes<I...>>{// Constructor. Evaluated at compile time.constexpr ALWAYS_INLINE MetaString(const char* str): key_(K), buffer_{ encrypt(str[I], I)... } { }// Runtime decryption. Most of the time, inlinedinline const char* decrypt(){for (size_t i = 0; i < sizeof...(I); ++i)buffer_[i] = decrypt(buffer_[i], i);buffer_[sizeof...(I)] = 0;//LOG("--- Implementation #" << 1 << " with key 0x" << hex(key_));return const_cast<const char*>(buffer_);}private:// Encrypt / decrypt a character of the original string with the keyconstexpr char key(size_t position) const { return static_cast<char>(key_ + position); }constexpr char ALWAYS_INLINE encrypt(char c, size_t position) const { return c ^ key(position); }constexpr char decrypt(char c, size_t position) const { return encrypt(c, position); }volatile int key_; // key. "volatile" is important to avoid uncontrolled over-optimization by the compilervolatile char buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte};// Partial specialization with a list of indexes I, a key K and algorithm N = 2// Shift the value of each character and does not store the key. It is only used at compile-time.template<char K, int... I>struct MetaString<2, K, Indexes<I...>>{// Constructor. Evaluated at compile time. Key is *not* storedconstexpr ALWAYS_INLINE MetaString(const char* str): buffer_{ encrypt(str[I])..., 0 } { }// Runtime decryption. Most of the time, inlinedinline const char* decrypt(){for (size_t i = 0; i < sizeof...(I); ++i)buffer_[i] = decrypt(buffer_[i]);//LOG("--- Implementation #" << 2 << " with key 0x" << hex(K));return const_cast<const char*>(buffer_);}private:// Encrypt / decrypt a character of the original string with the key// Be sure that the encryption key is never 0.constexpr char key(char key) const { return 1 + (key % 13); }constexpr char ALWAYS_INLINE encrypt(char c) const { return c + key(K); }constexpr char decrypt(char c) const { return c - key(K); }// Buffer to store the encrypted string + terminating null byte. Key is not storedvolatile char buffer_[sizeof...(I) + 1];};// Helper to generate a keytemplate<int N>struct MetaRandomChar{// Use 0x7F as maximum value since most of the time, char is signed (we have however 1 bit less of randomness)static const char value = static_cast<char>(1 + MetaRandom<N, 0x7F - 1>::value);};}
}// Prefix notation
//#define DEF_OBFUSCATED(str) andrivet::ADVobfuscator::MetaString<andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 3>::value, andrivet::ADVobfuscator::MetaRandomChar<__COUNTER__>::value, andrivet::ADVobfuscator::Make_Indexes<sizeof(str) - 1>::type>(str)
//#define OBFUSCATED(str) (DEF_OBFUSCATED(str).decrypt())#define DEF(str) andrivet::ADVobfuscator::MetaString<andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 3>::value, andrivet::ADVobfuscator::MetaRandomChar<__COUNTER__>::value, andrivet::ADVobfuscator::Make_Indexes<sizeof(str) - 1>::type>(str)
#define O(str) (DEF(str).decrypt())

对于上述代码,表面看使用了双引号字符串,实际上在编译时对代码中O("xxx")的内容都是以宏定义的方式进行了转换处理,生成的PE文件中并没有双引号字符串的直接暴露,既符合shellcode编写规范,又一定程度提高了开发效率。

注意

使用ADVobfuscator来自动处理双引号字符串时,不能禁用项目“优化”选项,即工程 “属性”--->“C/C++”--->“优化”中,“优化”选项可以选择“/O1”、“/O2”,或者“/Ox”,不能使用“已禁用 (/Od)”,否则字符换处理无效。


如果有任何问题,可以在我们的知识社群中提问和沟通交流:

图片​​

一个人走得再快,不如一群人走得更远!🤜🤛


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1421495.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

探索数字社交的奇迹:解读Facebook的革命性影响

1. 社交互动的全新模式 Facebook的出现不仅仅是一个社交媒体平台的诞生&#xff0c;更是一种全新的社交互动模式的开启。传统的社交模式主要依赖于面对面的交流&#xff0c;而Facebook则将社交推向了全新的数字化平台&#xff0c;使得人们可以在虚拟的世界里建立和维系社交关系…

sql注入---sqli靶场

1.什么是SQL注入 SQL注入是比较常见的网络攻击方式之一&#xff0c;它不是利用操作系统的BUG来实现攻击&#xff0c;而是针对程序员编写时的疏忽&#xff0c;通过SQL语句&#xff0c;实现无账号登录&#xff0c;甚至篡改数据库 2.sql注入原理 攻击者注入一段包含注释符的SQL语…

AI大模型探索之路-训练篇22: ChatGLM3微调实战-从原理到应用的LoRA技术全解

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

【CSP CCF记录】202109-2 非零段划分

题目 过程 思路 参考&#xff1a;http://t.csdnimg.cn/XRKTm STL库用法 unique用法 unique是STL中很实用的函数之一&#xff0c;需要#include&#xff08;感谢各位提醒&#xff09;&#xff0c;下面来简单介绍一下它的作用。 unique的作用是“去掉”容器中相邻元素的重复…

【Qt】之【CMake】Error : The source.. does not match the soused

QT中cmak编译出现CMake Error: The source… does not match the soused 分析 前提是该项目是从另一个路径的项目复制过来的&#xff0c;编写代码时发现无论怎样修改代码&#xff0c;运行后都没有任何变化&#xff0c;以为是qtbug&#xff0c;重构重启都没用&#xff0c;最后…

ICode国际青少年编程竞赛- Python-5级训练场-多参数函数

ICode国际青少年编程竞赛- Python-5级训练场-多参数函数 1、 def go(a, b):Spaceship.step(2)Dev.step(a)Spaceship.step(b)Dev.turnRight()Dev.step(b)Dev.turnLeft()Dev.step(-a) Dev.turnLeft() Dev.step(3) Dev.step(-3) go(3, 2) go(6, 1) go(5, 2) go(4, 3)2、 def go(…

docker搭建mysql集群实现主从复制

前言 随着业务的增长&#xff0c;一台数据服务器已经满足不了需求了&#xff0c;负载过重。这个时候就需要减压了&#xff0c;实现负载均衡和读写分离&#xff0c;一主一丛或一主多从。 主服务器只负责写&#xff0c;而从服务器只负责读&#xff0c;从而提高了效率减轻压力。 …

会声会影2024中文旗舰免费版(Corel VideoStudio)下载安装包附带会声会影软件注册机

一、软件背景及版本概述 会声会影&#xff08;Corel VideoStudio&#xff09;是由加拿大Corel公司发布的一款视频编辑软件&#xff0c;该软件以其功能丰富、操作简便而广受好评。2024年版本在继承之前版本优点的基础上&#xff0c;进行了诸多创新和改进&#xff0c;为用户提供…

只需三步,教你轻松搞定内网穿透

最近开发过程中又遇到了需要外网访问内部服务接口的需求&#xff0c;比如调用三方服务的各种回调通知、支付成功回调、大模型回调等都需要外部服务器来访问内部的接口&#xff0c;这里有个问题就是如果我们在本地或者测试环境调试的过程中我们使用的是内网环境&#xff0c;那外…

ABeam德硕 | 大语言模型系列(3):企业如何拥抱大语言模型

继前两期我们分享了大语言模型的概要简介及商业模式、商业价值之后&#xff0c;作为大语言模型系列的收尾篇&#xff0c;本期我们将聚焦在大语言模型的落地&#xff0c;结合案例简单分析拥抱大语言模型的思路&#xff0c;为企业提供ABeam见解。 往期回顾 ABeam Insight | 大语…

分享一个适用于 Vue 非常好用的移动端组件库【Vant 】

一、介绍 Vant 是一款轻量、可靠的移动端 Vue 组件库&#xff0c;由 Youzan UI 团队开发和维护。它专注于移动端 UI 组件的设计和实现&#xff0c;为开发者提供了一套完整的、高质量的组件集合&#xff0c;帮助开发者快速构建出符合移动设计规范的应用。 以下是 Vant 的一些主…

1070: 邻接矩阵存储简单路径

解法&#xff1a; #include<iostream> #include<vector> using namespace std; int arr[100][100]; int n; int sta, des; vector<int> path; vector<vector<int>> res; void dfs(vector<int> &a,int i) {a[i] 1;path.push_back(i);…

WINDOWS下zookeeper突然无法启动但是端口未占用的解决办法(用了WSL)

windows下用着用着时候突然zookeeper启动不了了。netstat查也没有找到端口占用&#xff0c;就是起不来。控制台报错 java.lang.reflect.UndeclaredThrowableException: nullat org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:147) ~…

APK签名

有些没签名的apk在高版本的安卓系统是无法运行的&#xff0c;就需要进行签名。 签名需要2个步骤 反编译回编译签名 使用到的工具 ApkTool &#xff0c; 免费获取地址&#xff1a; https://githubs.xyz/boot?app58 ApkTool运行需要安装java环境&#xff0c;如果你有了&…

一个API接口对接ChatGPT3.5/4.0,Claude3,文心一言,通义千问,智谱AI等多款AI模型,打造属于自己的AI应用

今天我要给大家介绍团队的最新项目——一个集成了ChatGPT-3.5/4.0、Claude3、文心一言、通义千问、智谱AI等多个AI模型的API模型聚合平台。仅需使用一个接口就可以对接所有AI模型 为什么要创建这个平台&#xff1f; 随着不同的AI模型陆续问世&#xff0c;每个模型都有其独特…

HarmonyOS应用模型Stage基本介绍

文章目录 <font colorcoral> HarmonyOS应用模型概况<font colorcoral> Stage模型基本概念<font colorcoral> Stage模型UIAbiliry的生命周期<font colorcoral> Stage模型的配置文件<font colorcoral> 写在后面的话<font colorcoral>Referen…

Hadopp入门之基础概念

Hadoop概述 Hadoop是什么 Hadoop是一个由Apache基金会所开发的分布式系统基础架构主要解决海量数据的存储和海量数据的分析计算问题广义上来说&#xff0c;Hadoop通常是指一个更广泛的概念——Hadoop生态圈 Hadoop优势 高可靠性&#xff1a;Hadoop底层维护多个数据副本&…

C++指针和动态内存分配细节,反汇编,面试题05

文章目录 20. 指针 vs 引用21. new vs malloc 20. 指针 vs 引用 指针是实体&#xff0c;占用内存空间&#xff0c;逻辑上独立&#xff1b;引用是别名&#xff0c;与变量共享内存空间&#xff0c;逻辑上不独立。指针定义时可以不初始化&#xff1b;引用定义时必须初始化。指针的…

【C -> Cpp】由C迈向Cpp (5):深入构造函数

标题&#xff1a;【C -> Cpp】由C迈向Cpp&#xff08;5&#xff09; 水墨不写bug &#xff08;图片来源于网络&#xff09; 不抵制失败&#xff0c;携手失败&#xff0c;迈向成功 正文开始&#xff1a; &#xff08;一&#xff09;深入理解构造函数 在之前的讲解中&#x…

【手势操作-复习前一天的内容-预习今天的内容 Objective-C语言】

一、昨天呢,我们学习的是这个,事件 1.事件这一块儿呢,iOS事件,分为三大类, 1)触摸事件 2)加速计事件 3)远程控制事件 2.这个里边呢,我们主要学习的是这个触摸事件,触摸事件里边,就是Touch,touchesBegan:方法里边,有一个touches参数,它是set类型的, 3.Set,…