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

ida81输入密码验证算法分析以及破解思路

本文分析了ida81对输入密码的验证流程,分别对输入密码到生成解密密钥、密码素材的生成过程以及文件数据的加密过程这三个流程进行分析,并尝试找一些可利用的破绽。很遗憾,由于水平有限,目前也只是有个思路未能完全实现,故分享出来抛砖引玉。

1. 密码验证算法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

proc m4ZQu {password LZQjH} {

    set ::maui::util::H6VeX ""

    set ::maui::util::EL0BW [string repeat \\0 32]

    package require tcltwofish

    package require sha256

    if {[string length $LZQjH] == 0} {

        error "Unable to initialize encryption - missing essential data"

    }

     

    //1.展开payload 获取相关参数

    if {[binary scan $LZQjH Ia16a32a64a32a* times iv passwordKey encryptedKey payloadIVsHash encryptedPayloadIVs] < 6} {

        error "Unable to initialize encryption - header missing or corrupt"

    }

    //2.使用输入的密码计算sha256,然后根据迭代次数times加密passwordkey,最后计算结果的sha256

    set iHcWR [a64bL $password $passwordKey $iv $times]

     

    //3.取上一步中的后32字节

    set BJvoG [string range [tcltwofish::decrypt $iHcWR $encryptedKey] 32 63]

     

    //4.使用上一步中的结果作为key 循环times/64次 解密encryptedPayloadIVs

    //这一步没有指定iv 实际过程为16个字节的0x00

    for {set 0} {$i < $times} {incr i 64} {

        set encryptedPayloadIVs [tcltwofish::decrypt $BJvoG $encryptedPayloadIVs]

    }

    //5.获取32字节后的数据

    set ZQpQw [string range $encryptedPayloadIVs 32 end]

    //6.计算上一步结果的sha256,和预置的hash比对,一致则密码正确

    if {[sha2::sha256 -bin $ZQpQw] != $payloadIVsHash} {

        maui::d_RUj "Invalid payload password"

    }

     

    //7.使用第五步中的结果作为后续选取iv的数据

    set ::maui::util::H6VeX $ZQpQw

    //8.使用第三步中的结果作为密钥

    set ::maui::util::EL0BW $BJvoG

}

在这个过程中,第一步需要的payload为4020字节,这是已知的。意味着可以获取到第六步中正确的hash结果。
然而,根据下面的帖子总结,ida的密码选取字符为58个,密码长度为14个字符,这个测试结果是非常大的。
破密行動: 以不尋常的角度破解 IDA Pro 偽隨機數 | DEVCORE 戴夫寇爾
[下载] ida 8.1-资源下载-看雪-安全社区|安全招聘|kanxue.com

而我在i9-13900K测试从随机生成输入密码到第六步验证hash整个过程,测试一个密码就需要0.045秒。所以手里有超算也不建议直接爆破。

2. 密码素材的生成过程

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

//根据输入密码生成payload

proc yOZ7q {password {times 16000}} {

        set ::maui::util::H6VeX ""

        set ::maui::util::EL0BW [string repeat \\0 32]

        package require tcltwofish

        package require sha256

         

        set BJvoG [qA4kM 32]

        set passwordKey [qA4kM 32]

        set ZQpQw [qA4kM [expr {16 * 256}]]

        set payloadIVsHash [sha2::sha256 -bin $ZQpQw]

        set encryptedPayloadIVs "[qA4kM 32]$ZQpQw"

        for {set 0} {$i < $times} {incr i 64} {

            set encryptedPayloadIVs [tcltwofish::encrypt $BJvoG $encryptedPayloadIVs]

        }

        set iv [qA4kM 16]

        set iHcWR [a64bL $password $passwordKey $iv $times]

         

        set encryptedKey [tcltwofish::encrypt $iHcWR "[qA4kM 32]$BJvoG"]

        set LZQjH [binary format Ia16a32a64a32a* $times $iv $passwordKey $encryptedKey $payloadIVsHash $encryptedPayloadIVs]

        set ::maui::util::H6VeX $ZQpQw

        set ::maui::util::EL0BW $BJvoG

         

        return $LZQjH

    }

//生成随机数据

 proc qA4kM {length} {

        set YKL8w ""

        if {[RLPut unix]} {

            foreach xML4B {/dev/urandom /dev/random} {

                if {[catch {

                    set WyLEv [open $xML4B r]

                    fconfigure $WyLEv -translation binary

                    set YKL8w [read $WyLEv $length]

                    close $WyLEv

                }]} {

                    catch {close $WyLEv}

                }  else  {

                    break

                }

            }

        }  else  {

         

        }

        if {[string length $YKL8w] != $length} {

            incr length -[string length $YKL8w]

            while {$length >= 2} {

                append YKL8w [binary format S [expr {int([maui::util::rand] * 0x10000)}]]

                incr length -2

            }

            if {$length > 0} {

                append YKL8w [binary format c [expr {int([maui::util::rand] * 0x100)}]]

            }

        }

        return $YKL8w

    }

    proc rand {} {

        if {[maui::util::RLPut "windows"] && [info commands ::bitrock::secure::rand_s] != ""} {

            if {[catch {

                set r [::bitrock::secure::rand_s]

            } V77Ls]} {

                maui::util::debug "failed to call rand_s: $V77Ls"

                set r [expr {rand()}]

            }

        else {

            set r [expr {rand()}]

        }

        return $r

    }

继续分析输入密码的时生成payload的算法,根据安装密码生成payload的过程中,很多数据包括最后解密数据用的密钥BJvoG也是随机生成的,如果这部分随机数生成流程能复现那也是可以破解的。仔细看随机数的生成,已经排除了以前的LCG随机数生成算法,换成了更安全的,前后状态无影响的方式,linux或unix下用/dev/random或者/dev/urandom,windows下调用rand_s。
rand_s | Microsoft Learn

3. 文件数据加密流程

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

proc MmyBM {compressionAlgorithm command data} {

        if {[catch {

            //1.压缩数据

            if {($compressionAlgorithm == "lzma") || ($compressionAlgorithm == "lzma-ultra") || ($compressionAlgorithm == "lzham") || ($compressionAlgorithm == "lzham-ultra")} {

                set data [eval [concat $command [list $data]]]

            }  else  {

                set data [vfs::zip -mode compress -nowrap 1 $data]

            }

            //2.1 前面添加四个字节的长度,然后末尾补全32的倍数

            //2.2 前面添加32字节的随机数据

            set data [qA4kM 32][UOijU $data 32

            //3.在H6VeX中截取16字节的iv

            set PG2JA [expr {int([maui::util::rand] * 0x100)}]

            set iv [string range $::maui::util::H6VeX [expr {$PG2JA * 16}] [expr {$PG2JA * 16 + 15}]]

            //4.计算crc32

            set hbA8n [format 0x%08x [expr {[zlib crc32 $data] & 0xffffffff}]]

             

            //5.使用EL0BW中的数据作为key 加密

            set data [tcltwofish::encrypt $::maui::util::EL0BW $data iv]

             

            //6. 前面填充四个字节的crc32以及选取iv的位置,共加了五个字节

            set YKL8w [binary format Ica* $hbA8n $PG2JA $data]

        } V77Ls]} {

            set ykaki $::errorCode

            set qXoNi $::errorInfo

            maui::util::debug "encryptPayload: error encrypting: $V77Ls"

            error $V77Ls $qXoNi $ykaki

        }

        return $YKL8w

    }

1

2

3

4

5

6

7

8

9

proc UOijU {data DeSRF} {

    //1. 将四字节的长度添加在数据前

    set data [binary format Ia* [string length $data] $data]

    //2. 计算末尾添加padding的长度

    set add [expr {($DeSRF - ([string length $data] % $DeSRF)) % $DeSRF}]

    //3. 生成随机padding并附加在末尾

    append data [qA4kM $add]

    return $data

}

再看看文件数据的加密流程。从上面的脚本中,可以看到加密前的数据结果为 32字节随机数据+4字节数据+$data+最后补全32字节的padding 然后使用twofish进行加密。而twofish是分组加密算法,所以加密过程就是下面这样的


通过在前面添加32字节的随机数据,猜测是为了避免明文攻击。因为很多文件前面都有固定字节的数据

比如sqlite3数据库的前16字节固定为SQLite format 3\x00,在ECB模式下,相同密钥加密任何sqlite3数据库的前16个字节都是一样的。所以衍生出了CBC模式,在每个分组加密之前用iv或者上一个密文分组异或明文以产生不一样的数据。

然而,这个例子中前面32个字节的随机数的使用却颇有点画蛇添足的味道。
首先,它不能掩盖明文数据或者阻止明文攻击(稍后提到),其次因为这32字节的加密数据,我们在后面进行密码分析的时候可以忽略了原本的初始iv,初始iv来自哪里,来自输入密码后进行的16000次twofish加密和256次twofish解密后生成的0x1000字节的encryptedPayloadIVs,而现在却可以跳过了,从而暴露了它的阿克琉斯之踵。根据密码算法,现在解密每一段文件数据时只需要从第三个分组的数据开始解密即可,输入iv来源于上一个分组的的密文(即第二个分组),输入的key对所有文件都是一样的(也就是本次要分析出来的目标)。

再回头说说有哪些明文,从脚本可知加密的第三个分组前四个字节为加密数据的长度。在安装过程中会生成installbuilder_installer_{random}.log文件,统计生成的文件数。

在hook解密函数的过程中也发现了同样数量的加密数据,而这些数据中最小长度为0x000012a0,最大为0x00040060。所以这1212个文件在相同的密钥解密之后的前四个字节肯定是
00 0x xx xx。如果能将每段加密数据对应到具体的文件,可能还会有更多的明文信息。

综上所述,根据解密的tcl安装脚本共分析了三种破解思路:
第一种,根据输入密码爆破,工作量太大,PC上几乎不可能成功。
第二种,随机数攻击。新版本的安装程序摒弃了LCG算法的使用,使用了更加安全的随机数生成方式。
第三种,根据部分明文信息和1212个样本数据爆破32字节密钥,爆破的过程中每次验证只需要一次twofish解密16个字节即可。再配合密码差分分析,可以减少一定的尝试次数。有熟悉angr的大佬也可以尝试一下形式化验证的方式去破解。

另外,ida安装脚本中的twofish算法来源于GitHub - rageworx/libtwofish: TwoFish encryption library for modern C++ (dev.in progress)
,但是作了一些修改。文末附带校正后的版本,可以直接用。另外还有调试时用的frida脚本。

 

相关文章:

ida81输入密码验证算法分析以及破解思路

本文分析了ida81对输入密码的验证流程&#xff0c;分别对输入密码到生成解密密钥、密码素材的生成过程以及文件数据的加密过程这三个流程进行分析&#xff0c;并尝试找一些可利用的破绽。很遗憾&#xff0c;由于水平有限&#xff0c;目前也只是有个思路未能完全实现&#xff0c…...

C语言——贪吃蛇

一. 游戏效果 贪吃蛇 二. 游戏背景 贪吃蛇是久负盛名的游戏&#xff0c;它也和俄罗斯⽅块&#xff0c;扫雷等游戏位列经典游戏的⾏列。 贪吃蛇起源于1977年的投币式墙壁游戏《Blockade》&#xff0c;后移植到各种平台上。具体如下&#xff1a; 起源。1977年&#xff0c;投币式…...

Android sqlite 使用简介

进行Android应用开发时经常会用到数据库。Android系统支持sqlite数据库&#xff0c;在app开发过程中很容易通过SQLiteOpenHelper使用数据库&#xff0c;SQLiteOpenHelper依赖于Context对象&#xff0c;但是基于uiatomator1.0和Java程序等无法获取Context的应用如何使用数据库呢…...

UE地形系统材质混合实现和Shader生成分析(UE5 5.2)

前言 随着电脑和手机硬件性能越来越高&#xff0c;游戏越来越追求大世界&#xff0c;而大世界非常核心的一环是地形系统&#xff0c;地形系统两大构成因素&#xff1a;高度和多材质混合&#xff0c;此篇文章介绍下UE4/UE5 地形的材质混合方案----基于WeightMap混合。 材质层 …...

Git分支与Git标签的介绍及其场景应用

目录 一、Git分支 1.1 定义 1.2 基本概念 1.3 特点与优势 1.4 Git分支操作命令 1.4.1 查看分支 1.4.2 创建分支 1.4.3 删除分支 1.4.4 切换分支 1.4.5 创建并切换到新建分支 1.5 场景应用 1.5.1 前期准备 1.5.2 具体操作 二、Git标签 2.1 定义 2.2 类型 2.3 标…...

Three.js——基于原生WebGL封装运行的三维引擎

文章目录 前言一、什么是WebGL&#xff1f;二、Three.js 特性 前言 Three.js中文官网 Three.js是基于原生WebGL封装运行的三维引擎&#xff0c;在所有WebGL引擎中&#xff0c;Three.js是国内文资料最多、使用最广泛的三维引擎。既然Threejs是一款WebGL三维引擎&#xff0c;那么…...

第八章认识Express框架

目录 Express模块化路由 基本概述 基本使用 基本构建 案例项目 Express接收请求参数 基本概述 基本类别 Express接收GET请求参数 Express接收POST请求参数 Express接收路由参数 Express模块化路由 基本概述 在Express中&#xff0c;路由是指确定应用程序如何响应对…...

【K8s集群离线安装-kubeadm】

1、kubeadm概述 kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。这个工具能通过两条指令快速完成一个kubernetes集群的部署。 2、环境准备 2.1 软件环境 软件版本操作系统CentOS 7Docker19.03.13K8s1.23 2.2 服务器 最小硬件配置&#xff1a;2核CPU、2G内存…...

python工具CISCO ASA设备任意文件读取

​python漏洞利用 构造payload&#xff1a; /CSCOT/translation-table?typemst&textdomain/%2bCSCOE%2b/portal_inc.lua&default-language&lang../漏洞证明&#xff1a; 文笔生疏&#xff0c;措辞浅薄&#xff0c;望各位大佬不吝赐教&#xff0c;万分感谢。 免…...

TCP关闭的两种方法概述

一个TCP需要经过四次挥手才可以关闭连接&#xff0c;能够开启四次挥手的函数有两个&#xff1a; int close(int sockfd) int shutdown(int sockfd,int howto) 接下来就分别讲解一下这两个函数。 close()函数 函数原型 #include<unistd.h> int close(int sockfd)这个函…...

Git的Hooks机制

参考文章&#xff1a;详解如何在项目中使用git Hooks&#xff08;husky、yorkie&#xff09; git hooks钩子 git hooks是一些自定义的脚本&#xff0c;用于控制git工作的流程&#xff0c;分为客户端钩子和服务端钩子。  ~/work/step-time/ [master*] ll .git/hooks total…...

代码随想录算法训练营第四十九天|121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II

第九章 动态规划part10 121. 买卖股票的最佳时机 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最…...

Rust教程6:并发编程和线程通信

文章目录 线程初步join方法线程通信 Rust系列&#xff1a;初步⚙所有权⚙结构体和枚举类⚙函数进阶⚙泛型和特征 线程初步 在Rust中&#xff0c;开启多线程进行并发编程&#xff0c;只需调用thread::spawn&#xff0c;但这里有一个坑点&#xff0c;即spawn函数只有一个传入参…...

JVM在线分析-监控工具(jps, jstat, jstatd)

参考官方文档&#xff08;jdk11&#xff09; https://docs.oracle.com/en/java/javase/11/tools/troubleshooting-tools-and-commands.html#GUID-CB44BFBA-E5F9-4D80-8EE8-28E9F16BC451 1. 监控工具(jps, jstat, jstatd) jps -q Suppresses the output of the class name, J…...

Console LDAP 配置解密

之前通过短视频向大家介绍了 Console 如何集成 LDAP&#xff0c;但很多小伙伴反映按照视频里的配置后不成功。今天就结合小伙伴们反映的问题来跟大家详细介绍一下。 Console LDAP 完整的配置参数如下&#xff1a; 名称类型说明hoststringLDAP 服务器地址portintLDAP 服务器端口…...

node插件MongoDB(三)—— 库mongoose 的使用和数据类型(一)

前言 提示&#xff1a;使用mongoose 的前提是你安装了node和 MongoDB。 mongoose 官网文档&#xff1a;http://mongoosejs.net/docs/index.html 文章目录 前言一、安装二、基本使用1. 打开bin目录的mongod.exe文件2. 基本使用的代码&#xff08;连接mongodb 服务&#xff09;3.…...

基础(二)

基础&#xff08;二&#xff09; 字符串型 C风格&#xff1a;char 变量名[] “字符串值”&#xff1b; C风格&#xff1a;string 变量名 “字符串值” #include <iostream> using namespace std; #include <string>int main() {// C风格char str1[] "h…...

思维模型 目标效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。明确目标&#xff0c;激发内在动机。 1 目标效应的应用 1.1 目标效应在教育领域的应用-棉花糖实验 美国斯坦福大学心理学系的教授米歇尔&#xff08;Walter Mischel&#xff09;曾经进行了…...

【从0到1设计一个网关】性能优化---Netty线程数配置与JVM参数配置

文章目录 Netty线程介绍Netty实战配置JVM参数与ZGCJVM与ZGC调优Netty线程介绍 在Netty中有两个比较重要的线程概念,一个是BOSS线程,一个是Woker线程。 Boss线程组: Boss线程组通常负责处理接受客户端连接的工作,即处理ServerSocketChannel的连接事件。 Boss线程会监听并接…...

node插件MongoDB(五)—— 库mongoose 的模块化(五)

文章目录 一、使用mongoose 模块化的原因二、准备工作2. 启动mongo.exe 和mongod.exe 两个程序连接数据库 三、基本模块的拆分1、基本逻辑2、代码3、代码图示说明 四、在index.js 中进一步的拆分1.拆分原因2.新建model文件夹存储文档的结构对象3.代码4.代码实际演示和注意点 一…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...