西湖论剑 EasyVT

一道VT题
题目给了一个exe程序和一个.sys文件
.sys文件可以在winxp系统下开启VT
出题人好像参考了周壑老师的代码,驱动程序相似度极高
这个exe程序很古怪,作者用vs2017开发包进行编译,最后没有进行静态打包,导致不能直接运行在winxp上,我们需要补齐很多的dll依赖才能正常运行,很麻烦,感情作者一开始就没打算让我们动调?

一、分析题目

之前接触过VT,借用周壑老师的代码,手动回复函数名
0
.sys文件的核心部分在这里:
 
0
我们参考代码回复这些宏的名字
0
比较三环代码和驱动代码
0
 
0
三环的vm指令和驱动的宏名称是一 一定义的,就像一个小型的vm混淆

二、分析算法

算法上只有rc4加密和魔改的tea加密
分别在sub_401250 和 sub_4019C0函数中

三、exp

魔改tea解密
// VT

#include <stdio.h>  
#include <stdint.h>  
  void conver_to_hex(uint32_t* v){
    uint32_t v0=v[0], v1=v[1];
    printf("%02x",v[0] & 0x000000ff);
    printf("%02x",(v[0] & 0x0000ff00) >> 8);
    printf("%02x",(v[0] & 0x00ff0000) >> 16);
    printf("%02x",(v[0] & 0xff000000) >> 24);
    
    printf("%02x",v[1] & 0x000000ff);
    printf("%02x",(v[1] & 0x0000ff00) >> 8);
    printf("%02x",(v[1] & 0x00ff0000) >> 16);
    printf("%02x",(v[1] & 0xff000000) >> 24);
    puts("");
}

//解密函数  
//void decrypt (uint32_t* v, uint32_t* k) {  
//    uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */  
//    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */  
//    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */  
//    for (i=0; i<32; i++) {                         /* basic cycle start */  
//        v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);  
//        v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);  
//        sum -= delta;      
//    }                                              /* end cycle */  
//    v[0]=v0; v[1]=v1;  
//}  
// 魔改部分: 
//1、 sum=0x20000000
//2、 delta=0xC95D6ABF
//3、 v0 += ...   =>  v0 -= ...      ;  v1 -= ...    =>    v1+= ...
//4、等号右边 => v0 => v1  ; v1 => v0  
void decrypt (uint32_t* v, uint32_t* k) {  
    uint32_t v0=v[0], v1=v[1], sum=0x20000000, i;  /* set up */  
    uint32_t delta=0xC95D6ABF;                     /* a key schedule constant */  
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */  
    for (i=0; i<32; i++) {                         /* basic cycle start */  
        v0 -= ((v1<<4) + k2) ^ (v1 + sum) ^ ((v1>>5) + k3);              // k2 => Get_key_3_2_1    //   k3 => Get_key_2_1_3
        v1 += ((v0<<4) + k0) ^ (v0 + sum) ^ ((v0>>5) + k1);              // k1 => Get_key_1_0_0  //   k0 => Get_key_0_3_2
        sum -= delta;      
    }                                              /* end cycle */  
    v[0]=v0; v[1]=v1;  
}  

//
//void encrypt (uint32_t* v, uint32_t* k) {  
//    uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */  
//    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */  
//    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */  
//    for (i=0; i < 32; i++) {                       /* basic cycle start */  
//        sum += delta;  
//        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);  
//        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);  
//    }                                              /* end cycle */  
//    v[0]=v0; v[1]=v1;  
//}  
// 写出解密脚本:
 
//加密函数  
void encrypt (uint32_t* v, uint32_t* k) {  
    uint32_t v0=v[0], v1=v[1], sum=0x20000000, i;           /* set up */  

    uint32_t delta=0xC95D6ABF;                     /* a key schedule constant */  
    for( i = 0;i<32;i++){
        sum -= delta;
    }
    
    
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */  
    for (i=0; i < 32; i++) {                       /* basic cycle start */  
        sum += delta;  
        v1 -= ((v0<<4) + k0) ^ (v0 + sum) ^ ((v0>>5) + k1);  
        v0 += ((v1<<4) + k2) ^ (v1 + sum) ^ ((v1>>5) + k3);          //出错原因: 想当然的写成: v0 += ...  // v1 -= ...  // 而没有认真的考虑加密逻辑 
       
    }                                              /* end cycle */  
    v[0]=v0; v[1]=v1;  
}  
void Tea()
{
    
    unsigned int cip[8] = {
        0x5C073994, 0x0D805CB3, 0x87DDA586, 0x0317FB8E, 0x6520EF29, 0x5A4987AF, 0xEB2DC2A4, 0x38CF470E
    };
    unsigned int key[4] = {
        0x00102030, 0x40506070, 0x8090A0B0, 0xC0D0E0F0
    };
    for(int i = 0;i<4;i++){
        uint32_t v[2]={1,2},k[4]={2,2,3,4};
        v[0] =   cip[i*2];
        v[1] =   cip[i*2+1];
        k[0] = key[2];
        k[1] = key[0];
        k[2] = key[1];
        k[3] = key[3];

        encrypt(v, k);  
//        conver_to_hex(v);
        printf("0x%x 0x%x\n",v[1],v[0]);
    }

    
}

int main(){
    
    Tea();
    
    return 0;
}

rc4解密

from Crypto.Cipher import ARC4 as rc4cipher
from struct import *
def int2bytes(m):
    return pack("<I",m)

cip = [
    0xb89c12d5, 0xb17e7a2c,
    0xbf9842d1, 0xe6257321,
    0xedcd45d0, 0xb2262921,
    0xb99b49dc, 0xba722d2c
] 
flag = b""
key = b"04e52c7e31022b0b"
for i in range(4):
    enc = rc4cipher.new(key)
    c = int2bytes(cip[i*2]) + int2bytes(cip[i*2+1])
    res = enc.decrypt(c)
    flag += res[4:8] + res[:4]
print(flag)
flag即为:
81920c3758be43705ba154bb8f599846
 
ps
这道题基本不需要什么VT知识,只需要捋清逻辑,写出解密脚本即可
posted @ 2023-02-06 19:40  TLSN  阅读(87)  评论(0)    收藏  举报