Acronis Cyber Protect破解

大类
逆向
Crack
技术标签
逆向-Windows
优先级
High
开始日期
Feb 10, 2022
状态
Monitoring
Public
Public
最后更新
Feb 18, 2022

Step 1:逆向验证流程

校验流程

  • 在线校验:登录账户
  • 离线校验
    • 获取激活请求:registration_file.bin
      • 一个Base64 Encode后的JSON
      • 内部带有aakore_id、installation_id、installation_hwid、instance_name四个字段
    • 上传激活文件:activation_file.bin
      • 返回一个带有很多operations的json文件,同样是base64后的
    • 处理接口:http://127.0.0.1:9877/api/account_server/onprem_operations
      • 可定位到处理进程:account_server.exe

离线激活流程

  • account_server.exe基本情况:
    • golang,符号基本保留
    • IDA Pro 7.7 SP1可以解析其结构体,可以进行逆向
    • 花了几天时间解决了Golang多返回值的支持
  • 激活文件格式:
    • 激活文件样例
    • 很多个operation,似乎是先注册、然后关联账号,最后设置license key
    • 带有sign,具体签名逻辑未知
  • 逆向激活逻辑:
    • 具体验证位于git.acronis.com_ab_account_server_internal_logic_onprem_operations._ptr_OperationsFile.Verify
      • 计算sha256 sum后,使用rsa提供的VerifyPS5函数校验签名
      • 证书由git.acronis.com_ab_account_server_account_server.ParseConfig解析ValidationKeys并一路传入
 

Step 2:完成破解

破解思路:

  • 配置文件中竟然提供了override的配置项:on_prem_operations_override_validation_key
  • 修改配置文件替换激活文件签名证书,随后重签名

重新签名激活文件

  • 写这个工具的时候全是坑,Acronis将激活文件读入之后再重新serialize来计算checksum,导致json格式有多个地方与源文件有所不同,通过打断点取出变量内容后观察写了一些变换规则

破解修改配置文件来修改证书

  • 在onprem模式下,配置文件有校验checksum
    • 校验发生在main_parseConfig中,通过serialize程序的配置信息为一行行的内容来签名
    • 默认使用算法为sha256,而可选的checksum算法有md5 sha256 debug
    • 其中debug是将每行用”|” join的结果作为checksum
  • 由于他的serialize过程过于复杂,直接下断点在account_server_.exe中捕获checksum结果更方便。
    • git_acronis_com_abc_struct_checksum__ptr_HashCheckSumCalculator_Check
    • // git.acronis.com/abc/struct-checksum.(*HashCheckSumCalculator).Check error __golang git_acronis_com_abc_struct_checksum__ptr_HashCheckSumCalculator_Check( _ptr_structchecksum_HashCheckSumCalculator a1, interface_ a2, _slice_uint8 a3) { const char *v3; // rdi retval_187AD60 v4; // [rsp+18h] [rbp-30h] v4 = git_acronis_com_abc_struct_checksum__ptr_HashCheckSumCalculator_Sum(a1, a2); if ( v4.1.tab ) return v4.1; if ( v4.0.len == a3.len && runtime_memequal((__int64)v4.0.ptr, (__int64)a3.ptr, v4.0.len) ) return (error)0LL; fmt_Errorf(v3); return *(error *)&v4.0.cap; }

尝试修改配置:

  • 配置修改1:失败
- need_account_for_trial: true→false - allow_licenses_cloud_sync: true→false - restrict_licensing_for_deactivated: true→false - demo_mode_duration: 720h→100y - activation_frequency: 24h→100h
  • 配置修改2:成功
- need_account_for_trial: true->false - allow_licenses_cloud_sync: true->false - demo_mode_duration: 720h->876000h - replace all "acronis.com" to "acronis_.com" - add "on_prem_operations_override_validation_key"

尝试激活

  • 在docker中激活时总会莫名其妙出错,原因不明。
    • 无论是我自己签名的还是官方签名的都无法正常激活
    • 但多重启、重build几次docker之后又会正常
  • 在配置修改错误时会导致无法将license assign到具体设备上
    • 激活会成功,但是添加设备时显示没有license
    • 少改了几处后重新尝试激活又能成功了
  • 激活与installation_hwid相关,installation_hwid似乎和cpu信息有关,具体计算方式不明,需要慎重观察
 

Step 3:打包Docker

  • 继承自12.5的docker
    • 从centos的systemd换成了ubuntu的systemd,更加稳定易用
    • 每次生成新的machine id,希望它能每次build出不同的hwid
    • 用上了docker 1.2新出的syntax,可以直接将安装包mount进来了,不需要multistage复制来复制去了
  • persistence做了很久
    • 需要persist这些目录:"/home", "/var/lib/Acronis", "/var/lib/alsdb", "/etc/Acronis", "/opt/acronis/management_agent/var", "/var/etc_pass"
      • 继承12.5使用systemd在basic target之前将这些目录拷贝
      • 始终有问题,调研后发现之前的systemd unit写的一直不对。
        • systemd启动流程是local-fs.target→basic.target→sysinit.target→multi-user.target
        • DefaultDependencies不关的情况下,systemd会默认require sysinit,而我们希望能被basic require,导致循环依赖。
        • 正确写法是:
        • [Unit] Description=Sync /etc/passwd to config volume DefaultDependencies=no Requires=local-fs.target After=local-fs.target Before=sysinit.target [Service] Type=simple ExecStart=/usr/local/libexec/sync_passwd.sh [Install] RequiredBy=basic.target
    • /etc/passwd不能是符号链接,而我又想做持久化
      • 尝试通过osync同步,但其只支持目录同步
      • 找到了unison,支持只同步两个文件
      • 加了个systemd服务每5分钟执行一次同步
  • 自己的用户死活不能登录
    • 第一层问题:这个docker base image的systemd少了/lib/systemd/system/multi-user.target.wants里面的东西,导致systemd-user-sessions没起来,每次都存在/run/nologin,导致pam_nologin一直拒绝登录
      • ln -s ../systemd-user-sessions.service到wants目录即可
    • 第二层问题:acronis的pam鉴权工具没有支持密码登录
      • /etc/pam.d/acronisagent里面没有写password开头的directive,导致只有他一个白名单文件中的用户能登录(默认里面只有root)
      • 把/etc/pam.d/acronisagent整个注释掉扬了
  • docker命令:
docker run -d --name acronis_agent \ --restart always \ --privileged \ --net host \ --add-host nas-school6.misty.moe:172.17.0.1 \ -it \ ccr.ccs.tencentyun.com/misty/acronis_agent docker run -d --name acronis_server \ --restart always \ -v /volume1/docker/acronis_server/home:/home \ -v /volume1/docker/acronis_server/var_lib_Acronis:/var/lib/Acronis \ -v /volume1/docker/acronis_server/var_lib_alsdb:/var/lib/alsdb \ -v /volume1/docker/acronis_server/etc_Acronis:/etc/Acronis \ -v /volume1/docker/acronis_server/opt_Acronis_var:/opt/acronis/management_agent/var \ -v /volume1/docker/acronis_server/var_etc_pass:/var/etc_pass \ --tmpfs /tmp --tmpfs /run --tmpfs /run/lock -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -p 9877:9877 -p 7780:7780 \ --net=host \ --add-host nas-school6.misty.moe:172.17.0.1 -h nas-school6.misty.moe \ -it \ ccr.ccs.tencentyun.com/misty/acronis_server
    notion image