ida81输入密码验证算法分析以及破解思路
2023-11-2 17:51:59 Author: mp.weixin.qq.com(查看原文) 阅读量:15 收藏

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


if {[binary scan $LZQjH Ia16a32a64a32a* times iv passwordKey encryptedKey payloadIVsHash encryptedPayloadIVs] < 6} {
error "Unable to initialize encryption - header missing or corrupt"
}


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


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



for {set i 0} {$i < $times} {incr i 64} {
set encryptedPayloadIVs [tcltwofish::decrypt $BJvoG $encryptedPayloadIVs]
}

set ZQpQw [string range $encryptedPayloadIVs 32 end]


if {[sha2::sha256 -bin $ZQpQw] != $payloadIVsHash} {
maui::d_RUj "Invalid payload password"
}


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

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

在这个过程中,第一步需要的payload为4020字节,这是已知的。意味着可以获取到第六步中正确的hash结果。

然而,根据下面的帖子总结,ida的密码选取字符为58个,密码长度为14个字符,这个测试结果是非常大的。

https://devco.re/blog/2019/06/21/operation-crack-hacking-IDA-Pro-installer-PRNG-from-an-unusual-way/
https://bbs.kanxue.com/thread-277712-1.htm

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

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 i 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。

https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/rand-s?view=msvc-170
03
文件数据加密流程
proc MmyBM {compressionAlgorithm command data} {
if {[catch {


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]
}


set data [qA4kM 32][UOijU $data 32]


set PG2JA [expr {int([maui::util::rand] * 0x100)}]
set iv [string range $::maui::util::H6VeX [expr {$PG2JA * 16}] [expr {$PG2JA * 16 + 15}]]


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


set data [tcltwofish::encrypt $::maui::util::EL0BW $data 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
}

proc UOijU {data DeSRF} {

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

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

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算法来源于https://github.com/rageworx/libtwofish,但是作了一些修改。原文文末附带校正后的版本,可以直接用,另外还有调试时用的frida脚本。

看雪ID:龙卷风呼呼呼

https://bbs.kanxue.com/user-home-980588.htm

*本文为看雪论坛优秀文章,由 龙卷风呼呼呼 原创,转载请注明来自看雪社区

# 往期推荐

1、IOFILE exploit入门

2、入门编译原理之前端体验

3、如何用纯猜的方式逆向喜马拉雅xm文件加密(wasm部分)

4、反恶意软件扫描接口(AMSI)如何帮助您防御恶意软件

5、sRDI — Shellcode反射式DLL注入技术

6、对APP的检测以及参数计算分析

球分享

球点赞

球在看

点击阅读原文查看更多


文章来源: https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458527408&idx=1&sn=391e9ed7e169d8898f637bf4e1f6ba95&chksm=b18d163a86fa9f2c5e6bcdf4c8ab1b85995c63739edebe94d6b2b62d7e08ff0b3af3a811148c&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh