VM-onion
咕咕咕咕咕咕,菜狗更新了
概述
输入一堆数,加密顺序为:
简易运算加密 -> 类 TEA(魔改好多,问 AI 说是 Speck)
明文加密结果与密文进行校验,然后作为 Key 解密下一段 VM Code。
循环往复,如此套娃。
思路是:解决第一个数,后面用同样的方法进行“能工智人”即可,全自动化不会。
解决第一个数
首先是还原指令流,一般两种方法:写代码模拟或者 trace 打 log。
此处使用后者。
然后队友使用强大的钞能力进行了一波 AI 分析。得到第一层的大体逻辑。
AI 分析得到了上面概述说的大体流程,当然也结合了一些经验。
So,第二步,解密第一个数。
解密两步走
- 从 log 中提取关键值。
- 还原解密代码。
第一步,从 log 中提取关键值
需要提取的有简易运算加密的参数,以及 Speck 的参数。
00010223 .text:vm_execute+A96 mov rax, [rax+rcx] RAX=48F0E6421AC66DEA
00010223 .text:vm_execute+60B mov rcx, [rsp+rdi*8+328h+s] RCX=48F0E6421AC66DEA
00010223 .text:vm_execute+613 mov rdx, rcx RDX=48F0E6421AC66DEA
key0 = 0x36B1CC9FE433713D
提取于:00010223 .text:vm_execute:loc_55555556BE01 mov rax, [rax+rcx]; opcode 0x18: MOV reg, [BP+addr] - 从内存[BP+offset]加载到寄存器 RAX=36B1CC9FE433713D
key1 = 0xF97646D69C84EBD8
提取于:00010223 .text:vm_execute:loc_55555556BE01 mov rax, [rax+rcx]; opcode 0x18: MOV reg, [BP+addr] - 从内存[BP+offset]加载到寄存器 RAX=F97646D69C84EBD8
第二步,解密脚本
C 语言解密脚本如下:
#include <stdio.h>
#include <stdint.h>
// 32位循环移位
uint32_t ror32(uint32_t v, int s) { s &= 31; return (v >> s) | (v << (32 - s)); }
uint32_t rol32(uint32_t v, int s) { s &= 31; return (v << s) | (v >> (32 - s)); }
// speck解密
uint64_t vm_tea_decrypt(uint64_t input) {
uint32_t v0 = input & 0xFFFFFFFF;
uint32_t v1 = (input >> 32) & 0xFFFFFFFF;
uint32_t keys[27];
uint32_t r2 = 0xE433713D, r3 = 0x36B1CC9F, r4 = 0x9C84EBD8, r5 = 0xF97646D6;
for (int i = 0; i < 27; i++) {
keys[i] = r2;
if (i < 26) { uint32_t t0 = ror32(r3, 8) + r2; t0 ^= i; uint32_t t1 = rol32(r2, 3) ^ t0; r2 = t1; r3 = r4; r4 = r5; r5 = t0; } } for (int i = 26; i >= 0; i--) {
v1 ^= v0;
v1 = ror32(v1, 3);
v0 ^= keys[i];
v0 -= v1;
v0 = rol32(v0, 8);
}
return ((uint64_t)v1 << 32) | v0;
}
// reverse
uint64_t reverse_xor(uint64_t v) {
v ^= 0x8CB331163A92FC19ULL;
v += 0x5566488C9C5CF234ULL;
v ^= 0x5074D85B9194E696ULL;
v += 0x48F0E6421AC66DEAULL;
return v;
}
int main() {
uint64_t target = 0xDA19BA6B81C83F61ULL;
uint64_t after_tea = vm_tea_decrypt(target);
printf("TEA dec: 0x%016llx\n", after_tea);
uint64_t result = reverse_xor(after_tea);
printf("Result: 0x%016llx (%llu)\n", result, result);
return 0;
}
如此,我们就搓出来了……第一个数。那么剩下 29 个怎么办?能工智人,继续搓。
解密数据记录
enc: 0xda19ba6b81c83f61 key:0x36b1cc9fe433713d,0xf97646d69c84ebd8
02= a28f38bd0463522c
enc: 0x659391a5dc3522b3 key:0x8d85b3156df9f721,0x28e3d33340bc0884
01= bf11b34d0ce941cc
enc: 0x5538224d4c7a252akey:0x1d1a63b571be74bc,0x3e36eee3aac04cfd
14= ef320f9e6ae31520
enc: 0x9766ec5e9e3303c0key:0x66a2d5250151c6d, 0x6d20bd39b0f2badc
11= 36646367b78c2f91
以下省略...
ba610b6c5d80c91a
bf11b34d0ce941cc
a28f38bd0463522c
79ed5d84199dd9cb
4d9c56b2a1d77a0d
fe13c54ceb12fea8
494a63fc85b9953a
ad1f6be84bbb4680
cd05f91609d653fa
55493aa141fbe86f
25bc9aff736b80a8
d8817dda43824d2c
5fcca9a9cb65130d
6f3ed35da24dacfa
b5e1534e1dc36c87
ac1b4e2750778a01
c8f82d07316dcd3b
36646367b78c2f91
9eed7637cd5eaa26
ff546a0085041459
ef320f9e6ae31520
1e00a4b9e25488f6
1a9a0626a035fb9d
e2f1eb0e5248cd2c
8a0bf5239eed75c4
749e8082db34037d
f4d25540ed584887
c12422512500c887
7e1a125dcfa56359
497cff13eaa5bf76
d51ceddab7795459
a922933b0b315a10
cabd557ffa1df043
e0459b855188d045
82700d6f6a986873
c01552dff3a12f67
0615548ece7312fb
0e189fa829657913
8d4c8f2124957228
451572c65bcb3425
554fca602792e879
4f749f6bbca2014c
b1e1adc831c8d567
9c73a6d3f711e66e
2ab305ec4e07b0b4
98a16d274bb044d2
c409de0e72c1029e
5e68e47d3a360a80
a1570f48caceb3dd
d6ab1c9a18ebb936
RCTF{VM_ALU_SMC_RC4_SPECK!_593eb6079d2da6c187ed462b033fee34}
下次碰到套娃题,一定写解释器模拟自动化((
rctfSpeak Softly Love
根据视频试图先找到电脑型号,然后结合关键词music,youtube搜索找到这个。
8ssDGBTssUI
根据评论区找到主页
主页里
想联系我吗?我的电子邮件地址与此网页的地址几乎相同(firstname@lastname.fr)。
令人惊讶的是,很多人难以念出我的名字,所以这里附上我的名字(图片来自 Wikimedia)。
https://mateusz.viste.fr/mateusz.ogg
发表回复