使用SCA逆向VM虚拟机

2022-12-31 0 564

使用SCA逆向VM虚拟机

序言

SCA又称为侧链路反击,中心思想是透过运转这时候各式各样重要信息对流程展开反击。主要包括单纯耗电预测反击(SimplePower Analysis attacks,SPA)和脉冲响应耗电预测反击(Differential Power Analysis attacks,DPA),与现代公钥预测学较之,此种反击方式反击。

VM身份验证

这儿采用的是他们写的两个CrackMe,不采用除IO的任何人控制系统表达式

#include

#include

const char key[] = {104, 100, 107, 125, 108, 118, 100, 99, 96};

int main() {

char input[10] = {0};

   scanf(“%9s”, input);

   if (strlen(input) != 9) {

printf(“ERROR The length of key is 9 bytes!\n”);

       return -1;

  }

   for (int i = 0; i < 9; ++i) {

       if (input[i] != (key[9 – i – 1] ^ 5)) {

printf(“ERROR The key is incorrect!\n”);

           return -1;

      }

  }

   printf(“OK Thanks to your purchase!\n”);

   return 0;

}

编译后采用VMProtect对main表达式展开VM软件包保护

使用SCA逆向VM虚拟机

保护后采用IDA查看代码被替换了只剩下VM入口,代码是不可被直接阅读的

push xxx

call xxx

使用SCA逆向VM虚拟机

Block数量预测

这儿采用的是angr对身份验证后的二进制文件模拟执行

def main():

ql = Qiling([rf”{ROOTFS}/bin/main_vmp”], ROOTFS, stdin=pipe.SimpleInStream(sys.stdin.fileno()),stdout=pipe.SimpleOutStream(sys.stdout.fileno()))

对流程运转block展开hook,codeNum用来存放此次key所执行的block数

0x401010 – 0x504bB6 是VMP区段,我们仅仅记录该区段的block。

ql.hook_block(trace)

def trace(ql, addr, size):

  global codeNum

if addr – ql.loader.images[0].base in range(0x401010, 0x504bB6):

      codeNum += 1

密钥的生成

该流程的密钥由9个字节组成,字节的范围是0~2^16-1

这儿已知该流程的密钥组成是a-z,所以采用a-z展开反击

用a-z对每一位展开反击直到block数量增多

src = string.ascii_letters

codeNum = 0

codeNum1 = 0

indexs = [0] * 9

cur = 0

key = [a] * 9

def start(_ql: Qiling):

   global data

   global key

//前两个block数量

   global codeNum

   //当前block数量

   global codeNum1

   global cur

   //当前block > 前两个block

   if codeNum > codeNum1:

codeNum1 = codeNum

   //前两个block > 当前block

   elif codeNum1 > codeNum:

       //该位正确

       indexs[cur] -=2

       //回溯

key[cur] = src[indexs[cur]]

       //移动到下一位

       cur = cur + 1

   //新的一轮猜想

   codeNum = 0

   data = _ql.save()

   key[cur] = src[indexs[cur]]

indexs[cur] +=1

   key1 = “”.join(key).encode()

表达式开始与结尾

为了提升流程运转效率,这儿采用angr对VM头时的Context展开保存,拦截put表达式对结果展开判断

def start(_ql: Qiling):

   //存放当前的Context

   data = _ql.save()

   //写入猜想的key

   _ql.os.stdin.write(key1)

def end(_ql: Qiling):

   global codeNum

   //从edi寄存器取结果字符串

   read = str(_ql.mem.read(_ql.reg.rdi, 30))

   if “ERROR” in read:

//包含ERROR则还原环境展开下一次反击

       global data

       data = _ql.restore(data)

   else:

       cur = cur + 1

   global key

print(“密钥:”, “”.join(key[0:cur]).encode())

运转结果

等待了几十秒密钥便反击出来了

使用SCA逆向VM虚拟机

放到crackme中

使用SCA逆向VM虚拟机

完整代码

#!/usr/bin/env python3

import sys

from qiling.extensions import pipe

import string

from qiling import Qiling

ROOTFS = r”/home/mrack/qiling/examples/rootfs/x8664_linux”

src = string.ascii_letters

global data

global key

global codeNum

global codeNum1

global isFirst

codeNum = 0

codeNum1 = 0

indexs = [0] * 9

cur = 0

key = [a] * 9

def start(_ql: Qiling):

global data

    global key

    global codeNum

    global codeNum1

    global cur

    if codeNum > codeNum1:

        codeNum1 = codeNum

elif codeNum1 > codeNum:

        indexs[cur] -= 2

        key[cur] = src[indexs[cur]]

        cur = cur + 1

    codeNum = 0

    data = _ql.save()

key[cur] = src[indexs[cur]]

    indexs[cur] += 1

    key1 = “”.join(key).encode()

    _ql.os.stdin.write(key1)

def end(_ql: Qiling):

    global cur

    global codeNum

    read = str(_ql.mem.read(_ql.reg.rdi, 30))

    print(codeNum)

if “ERROR” in read:

        global data

        data = _ql.restore(data)

    else:

        cur = cur + 1

    global key

print(“密钥:”, “”.join(key[0:cur]).encode())

def trace(ql, addr, size):

    global codeNum

if addr – ql.loader.images[0].base in range(0x401010, 0x504bB6):

        codeNum += 1

def main():

ql = Qiling([rf”{ROOTFS}/bin/main_vmp”], ROOTFS, stdin=pipe.SimpleInStream(sys.stdin.fileno()),

                stdout=pipe.SimpleOutStream(sys.stdout.fileno()))

ba = ql.loader.images[0].base

    ql.hook_address(start, ba + 0x504168)

    ql.hook_address(end, ba + 0x05E0)

ql.hook_block(trace)

    ql.run()

if __name__ == “__main__”:

    main()

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务