2-自定义 String 哈希算法

文章首发于先知社区:https://xz.aliyun.com/news/18218arrow-up-right

先水一篇文章,这篇文章只是开胃前菜。

自定义 String 哈希算法的定义:将字符串映射为唯一的整数(哈希值)

公式:H(s)=唯一HASH值

特点

  1. 唯一性(抗碰撞性)​:理想状态下,不同输入应生成唯一哈希值,根据 鸽巢原理,哈希冲突必然存在,但是碰撞的概率是非常低的。

  2. 不可逆性(单向性):哈希函数设计为单向映射,从哈希值反推原始输入在计算上不可行(即使已知算法),大部分在线的HASH算法解密网站都是通过建立庞大的数据库,然后通过撞库的方式找到输入值对于的HASH值。

学过密码学的师傅,肯定对哈希算法不陌生,就比如在实际的生成环境中就有 MD5SHA256NTLM 等等HASH算法。在本节中我们不必考虑这些算法,而是使用简单的自定义 String 哈希算法,比如说 ROTR32CRC32 算法。

为什么要使用String 哈希算法呢?其理由如下

  1. 避免检测:主要的原因还是我们在很多情况下是需要动态获取API的,直接使用模块(kernel32.dll)API名称(如 "VirtualAlloc")会在二进制文件中留下明文字符串,容易被杀毒软件的静态签名检测识别,将模块和API名称转换为整数哈希值(如 0xA779563A),消除可读字符串特征,大幅降低静态分析风险。

  2. 减小shellcode体积:整数哈希值的大小大多数情况下都是32位(4个字节),而API和模块名称的一般都是比较长的且不固定,大多数是大于4个字节的(一个字符一个字节)。

一、ROTR32

ROTR32 算法是一种位运算操作,全称为“32位循环右移”(Rotate Right 32-bit)。其核心功能是将一个32位整数(unsigned int)的二进制表示向右循环移动指定的位数,移出的位从左侧重新填充。其计算公式如下

ROTR32(x,n)=(x≫n)∣(x≪(32−n))
  1. ​右移操作(x≫n)​​: 将 x 的二进制表示向右移动 n 位,​​高位补0​​,移出的低位直接丢弃。

  2. 左移操作(x≪(32−n))​:将 x 向左移动 32−n 位,​​低位补0​​,移出的高位丢弃。​

  3. 位或合并(∣):将右移和左移的结果按位合并,​​循环填充空缺位​​,最终实现“移出的低位补充到高位”的循环效果

这个算法在MSF和CS的的stager中被广泛使用,是一种高效且抗碰撞性良好的字符串哈希算法,可以用C语言、python和Go等高级语言实现,在x86/x64汇编中,已经将其浓缩成一个指令 ror

我这里实现的ROTR32算法计算出的hash值与在MSF和CS的的stager中的hash值不一样的,因为我改了部分计算逻辑。

1.1 C语言

1.2 python

因为Python有动态整数类型,所以rotr32算法需要稍微处理,

  1. shift %= 32,确保移动的位数固定在[0,31]里面,此操作非必须

  2. 一个数 & 0xFFFFFFFF:强制锁定32位范围(避免Python大整数干扰)

1.3 Go

1.4 MASM汇编

ws2_32.dll+WSAStartup = 4645344Ch ws2_32.dll+WSASocketA = 0B83D505Ah ws2_32.dll+connect = 6AF3406Dh ws2_32.dll+recv = 0F1606037h kernel32.dll+LoadLibraryA = 56590AE9h kernel32.dll+VirtualAlloc = 0FBFA86AFh kernel32.dll+GetProcAddress = 0E658B905h kernel32.dll+VirtualProtect = 0E3918276h Ekernel32.dll+ExitProcess = 0DE2D94D9h

汇编loop_modname做了部分修改,主要是与高级语言保持一致,不兼容往前文章给出的HASH值,请注意甄别

二、CRC32

在线CRC32检验:CRC在线计算arrow-up-right

学过计算机网络的师傅对CRC冗余校验码不陌生,CRC32(Cyclic Redundancy Check 32)是一种广泛应用的​​32位循环冗余校验算法​​,主要用于检测数据传输或存储过程中的意外错误(如网络传输、文件完整性校验)。其核心是通过多项式除法生成固定长度的校验码(32位),可以用做自定义String哈希算法。

这个算法我是在 pe_to_shellcode/loader_v1/hldr64/hldr64.asm at master · hasherezade/pe_to_shellcodearrow-up-right 中看到的,各位师傅可以参考项目给出的代码,自己去实现汇编代码。

大致流程

  1. ​初始化​​:crc = 0xFFFFFFFF

  2. ​混合字节​​:crc ^ 0x01 = 0xFFFFFFFE

  3. ​8 轮位操作​​:

    • 第 1 轮:0xFFFFFFFE & 1 = 0 → 右移 → 0x7FFFFFFF

    • 第 2 轮:0x7FFFFFFF & 1 = 1 → 右移并异或多项式 → (0x3FFFFFFF) ^ 0xEDB88320 ...(重复 8 次)

  4. ​最终取反​​:得到校验码

2.1 C语言

2.2 python

2.3 go

三、下一步计划

我将燃尽自己、全力以赴,倾注全部心血完成承诺已久的SRDI技术解析长文。这是一篇技术性非常强的文章,我是以写论文的态度去认真对待的,它的质量绝对不会让各位师傅失望,甚至可以说是整个互联网独一份的。

其实文章已经写好了,我还在做最后的精修,还有一些心里话我就放在下一篇文章了,文章很快就会发出来。

Last updated