当前位置: 首页 > news >正文

HTB Tracks - REVERSE - SimpleEncryptor

反汇编

int __fastcall main(int argc, const char **argv, const char **envp) { char v3; // al char v5; // [rsp+7h] [rbp-39h] unsigned int seed[2]; // [rsp+8h] [rbp-38h] BYREF signed __int64 i; // [rsp+10h] [rbp-30h] FILE *stream; // [rsp+18h] [rbp-28h] size_t size; // [rsp+20h] [rbp-20h] void *ptr; // [rsp+28h] [rbp-18h] FILE *s; // [rsp+30h] [rbp-10h] unsigned __int64 v12; // [rsp+38h] [rbp-8h] v12 = __readfsqword(0x28u); stream = fopen("flag", "rb"); fseek(stream, 0, 2); size = ftell(stream); fseek(stream, 0, 0); ptr = malloc(size); fread(ptr, size, 1u, stream); fclose(stream); seed[0] = time(0); srand(seed[0]); for ( i = 0; i < size; ++i ) { *(ptr + i) ^= rand(); v3 = rand(); v5 = *(ptr + i); seed[1] = v3 & 7; *(ptr + i) = __ROL1__(v5, v3 & 7); } s = fopen("flag.enc", "wb"); fwrite(seed, 1u, 4u, s); fwrite(ptr, 1u, size, s); fclose(s); return 0; }

逆向分析程序逻辑

首先,我们分析这个程序的功能:

  1. 读取flag文件

    • 以二进制模式打开flag
    • 获取文件大小size
    • 使用malloc()分配内存ptr,并将flag的内容读取到ptr中。
  2. 初始化srand()种子

    • seed[0] = time(0),使用当前时间作为伪随机数生成器的种子。
    • srand(seed[0])初始化 PRNG(伪随机数生成器)。
  3. 加密流程

    • 每个字节执行两个步骤
      1. *(ptr + i) ^= rand():用rand()生成的值对当前字节进行异或加密。
      2. *(ptr + i) = __ROL1__(v5, v3 & 7):对当前字节进行循环左移(ROL1),移动位数为rand() & 7(相当于0-7位)。
  4. 写入flag.enc

    • seed[0](4字节)写入flag.enc(前 4 字节)。
    • 然后把加密后的ptr写入flag.enc

解密思路

要解密flag.enc,我们需要:

  1. 读取前 4 字节,获取seed[0]
  2. 重建srand(seed[0]),使得rand()序列与加密时一致。
  3. 逆向加密操作
    • 对每个字节:
      1. 循环右移(ROR)rand() & 7位(因为 ROL 的逆操作是 ROR)。
      2. 再次异或rand()(因为A ^ B ^ B = A)。
  4. 输出解密后的数据。

解密脚本(Python)

import struct import ctypes import sys # 定义 ROL/ROR(C 风格的循环移位) def rol(val, bits, width=8): return (val << bits % width) & (2**width - 1) | ((val & (2**width - 1)) >> (width - (bits % width))) def ror(val, bits, width=8): return rol(val, width - bits % width, width) def decrypt(filename): with open(filename, "rb") as f: data = f.read() seed = struct.unpack("<I", data[:4])[0] # 读取前4字节,小端序 enc_data = data[4:] # 加密的数据部分 # 重建 srand(seed) import random random.seed(seed) decrypted = bytearray(enc_data) for i in range(len(decrypted)): # Step1: Reverse __ROL1__(v5, rand() & 7) => __ROR1__(v5, rand() & 7) rshift_bits = random.getrandbits(32) & 7 decrypted[i] = ror(decrypted[i], rshift_bits) # Step2: Reverse XOR with rand() rval = random.getrandbits(32) & 0xFF decrypted[i] ^= rval return bytes(decrypted) if __name__ == "__main__": if len(sys.argv) != 2: print("Usage: python decrypt.py flag.enc") sys.exit(1) output = decrypt(sys.argv[1]) print("Decrypted:", repr(output))

使用方法

python3 decrypt.py flag.enc

验证

  • 加密过程flagROL1 + XORflag.enc
  • 解密过程flag.encROR1 + XORflag

由于rand()是基于seed[0]生成的确定序列,解密时可以正确恢复flag

Analysis

Theencryptexecutable reads a file namedflag, encrypts it, and writes the output toflag.enc. Disassembling the binary reveals the following encryption procedure:

It seeds the random number generator using the current time:srand(time(NULL)). It first writes the 4-bytetimeseed toflag.enc. For each byte of the flag, it generates two random numbers usingrand():r1 = rand() & 0xffr2 = rand() & 7The byte is XORed withr1, and then rotated left (ROL) byr2bits. The resulting byte is appended to the encrypted file.

Solution

Since the seed is written to the first 4 bytes offlag.enc, we can simply extract it and reverse the encryption process. The decryption reverses the steps by rotating the encrypted byte right (ROR) byr2bits, and then XORing the result withr1.

I wrote a python script (solve.py) usingctypesto load the C standard library (libc.so.6) to match the exact sequences of pseudorandom numbers generated byrand():

import ctypes # Load libc libc = ctypes.CDLL('libc.so.6') # Open encrypted file with open('flag.enc', 'rb') as f: data = f.read() # Parse seed (first 4 bytes) seed = int.from_bytes(data[:4], 'little') enc_flag = data[4:] # Seed libc to match the generator state libc.srand(seed) def ror(val, r_bits): r_bits = r_bits % 8 return ((val >> r_bits) | (val << (8 - r_bits))) & 0xff dec_flag = bytearray() for c in enc_flag: r1 = libc.rand() & 0xff r2 = libc.rand() & 7 # Reverse left rotation (ROL) with a right rotation (ROR) c_xored = ror(c, r2) # Reverse XOR dec_c = c_xored ^ r1 dec_flag.append(dec_c) print("Decrypted Flag:", dec_flag.decode('utf-8', errors='ignore'))
http://www.jsqmd.com/news/463454/

相关文章:

  • Python中继承带来的问题
  • NFTMarket 1 | NFT 简介、业务、技术方案
  • 四字节十六进制转化为单精度IEEE 754 浮点数
  • 打开软件就弹出vccorlib120.dll如何修复? 附免费下载方法分享
  • Ray + LanceDB + Daft 构建大规模向量数据分析管道
  • 计算机软件资格考试——专业英语
  • 没有 Base Code 谈何重构?揭秘智能零零AI论文助手从 0 到 1 的大模型结构化生成引擎
  • 打开软件就弹出vcomp.dll如何修复? 附免费下载方法分享
  • macbookair安装openclaw
  • Ray 集群多用户资源隔离实践
  • MySQL 进阶:库与表的DDL核心操作全指南(含实战案例)
  • 工业 + AI 落地实践:JBoltAI在工业场景的应用解析
  • 打卡信奥刷题(2938)用C++实现信奥题 P5800 [SEERC 2019] Life Transfer
  • 单片机高阻态:数字电路中的“隐形守护者”
  • Qt开发与MySQL数据库教程(一)——配置MySQL
  • 数据|非rag的类人检索
  • Java团队转型AI应用开发:挑战与JBoltAI的破局之道
  • 打卡信奥刷题(2939)用C++实现信奥题 P5810 [SCOI2004] 文本的输入
  • 化学绘图效率革命:InDraw五大核心功能全解析,从OCR识别到CAS号检索的实战指南
  • JBoltAI视频SOP:让“工业+AI”更高效直观
  • Python爬虫实战:监控贝壳找房小区均价与挂牌增量!
  • 物联网毕业设计效率提升指南:基于STM32原理图的模块化设计与快速验证方法
  • Spring Boot WebClient性能比RestTemplate高?看完秒懂!
  • 打卡信奥刷题(2940)用C++实现信奥题 P5815 [CQOI2010] 扑克牌
  • MTools教育应用:智能批改系统开发实战
  • 次元画室生成网络拓扑图:运维与网络教学的AI助手
  • 1.9 电子商城核心链路质量保障:从下单到支付的测试实战拆解
  • 使用IDEA开发RVC模型Java调用客户端:工程化配置与调试技巧
  • Leaflet与turf.js实战:动态生成等值线图并实现精准值交互展示
  • ArcGIS坐标系实战:从基础概念到投影变换全解析