淺析QNX系統(tǒng)的shadowed密碼Hash格式
QNX(Quick UNIX)是一個(gè)unix家族的實(shí)時(shí)操作系統(tǒng),***發(fā)行于1980年,2010年被黑莓公司收購(gòu)。QNX通常用于嵌入式系統(tǒng)中,在企業(yè)服務(wù)器領(lǐng)域并不常見(jiàn)。參考資料[1]的博客中有一些QNX安全評(píng)估和滲透測(cè)試的信息。
QNX是一種商用的類Unix實(shí)時(shí)操作系統(tǒng),遵從POSⅨ規(guī)范,目標(biāo)市場(chǎng)主要是嵌入式系統(tǒng)。QNX成立于1980年,是加拿大一家知名的嵌入式系統(tǒng)開(kāi)發(fā)商。
QNX的應(yīng)用范圍極廣,包含了:控制保時(shí)捷跑車的音樂(lè)和媒體功能、核電站和美國(guó)陸軍無(wú)人駕駛Crusher坦克的控制系統(tǒng),還有RIM公司的BlackBerry PlayBook平板電腦。
如果你有幸在滲透測(cè)試或研究中接觸過(guò)QNX主機(jī),你可能會(huì)意識(shí)到/etc/shadow文件下的shadowed密碼使用了一種不常用的格式。本文中的這些經(jīng)驗(yàn)?zāi)軌驇椭憷斫馄湓恚⑶腋嬖V你如何爆破這種格式的hash值。
可輸出的hash格式
QNX系統(tǒng)將/usr/bin/passwd中的二進(jìn)制以可輸出的格式生成到/etc/shadow文件中。它包含了生成和解析這些hash值的所有邏輯數(shù)據(jù),這是逆向這個(gè)格式的***資源。
這個(gè)文件支持好幾種hash加密方法:MD5,SHA-{256,512},以及QNX遺留的不安全加密實(shí)現(xiàn)(參見(jiàn)CVE-2000-0250)。他們分別命名為md5_crypt,sha2_crypt,qnx_crypt。
另外,其同時(shí)還支持解析明文密碼的plain_crypt方法,但是這個(gè)你需要手動(dòng)修改/etc/shadow。 有趣的是,SHA-1支持比較老的版本,但是由于沒(méi)有鏈接庫(kù)調(diào)用路徑,所以沒(méi)有辦法使用。
QNX Neutrino 6.6.0默認(rèn)的hash方法是SHA-512,1000輪計(jì)算,并附帶16字節(jié)的鹽值(參考[2])。 用SHA-512對(duì)用戶賬號(hào)密碼附加8字節(jié)的鹽值做1000輪的計(jì)算生成的結(jié)果如下:
這是MD5和SHA-{256,512}的通用格式。QNX的hash加密方法,格式上很像傳統(tǒng)的Linux DES加密字符串。
1.Shadowed密碼文件用冒號(hào)(:)分割得到下面接個(gè)段: 2.username – 用戶名 3.@S,100@386d...truncated...da5d@129b6761 –可輸出的hash字符串(根據(jù)使用hash方法的不同而不同) 4.1448613322 – 設(shè)置密碼時(shí)產(chǎn)生的時(shí)間戳 5.0 – 未知 6.0 – 未知
面我還未找到***兩個(gè)值是用來(lái)干嘛的,但這兩個(gè)值總為0也許跟不可使用的賬戶有關(guān)。
可輸出的hash字符串又被@符號(hào)分割成下面這幾個(gè)段:
S,100 –前面表示使用的hash方法,后面表示加密計(jì)算輪數(shù) S -- SHA-512 s -- SHA-256 m -- MD5 p – 明文密碼 386d...truncated...da5d – 使用hash方法計(jì)算出的16進(jìn)制結(jié)果 129b6761 – 16進(jìn)制鹽值
Hash密碼例子
下面所有的例子都是密碼的hash值
SHA-512加密, 1000輪, 16字節(jié)鹽值
username:@S@60653c9f515eb8480486450c82eaad67f894e2f4828b6340fa28f47b7c84cc2b8bc451e37396150a1ab282179c6fe4ca777a7c1a17511b5d83f0ce23ca28da5d@caa3cc118d2deb23:1448585812:0:0
SHA-512加密, 1000輪, 8字節(jié)鹽值
username:@S@386d4be6fe9625c014b2486d8617ccfc521566be190d8a982b93698b99e0e3e3a18464281a514d5dda3ec5581389086f42b5dde023e934221bbe2e0106674cf7@129b6761:1448585864:0:0
SHA-256加密, 1000輪,16字節(jié)鹽值
username:@s@1de2b7922fa592a0100a1b2b43ea206427cc044917bf9ad219f17c5db0af0452@36bdb8080d25f44f:1448585954:0:0
MD5加密, 1000輪, 16字節(jié)鹽值
username:@m@bde10f1a1119328c64594c52df3165cf@6e1f9a390d50a85c:1448585838:0:
內(nèi)部二進(jìn)制代碼
從QNX Neutrino 6.6.0系統(tǒng)得到的/usr/bin/passwd 二進(jìn)制并不很令人興奮。 這是一個(gè)32位的可執(zhí)行文件,沒(méi)有剪去符號(hào)表和libc,ld-linux,linux-gate的動(dòng)態(tài)鏈接,能夠找到shadowed密碼文件的所有hash加密實(shí)現(xiàn)。
文件/etc/default/passwd會(huì)影響二進(jìn)制的行為,只有個(gè)QNXCRYPT指令存在于文件中時(shí)QNX加密方法才會(huì)被使用。另外一些有趣的指令,比如STRICTPASSWORD確保密碼使用至少兩個(gè)字符集、NOPASSWORDOK允許使用空白密碼。
函數(shù)gensalt使用系統(tǒng)時(shí)間初始化一個(gè)隨機(jī)算法來(lái)生成一個(gè)隨機(jī)值,如果想要深入挖掘可以使用initstate,setstate,random,srandom函數(shù)。我沒(méi)有很詳細(xì)看這幾個(gè)函數(shù),但是聚合熵少于8字節(jié)隨機(jī)操作會(huì)失敗。 該鹽值是16進(jìn)制字符串,如果設(shè)置為16字節(jié)就是16個(gè)字符。
qnx_crypt 已經(jīng)有說(shuō)明文檔,并且沒(méi)有修改。(參考文檔[3])
md5_crypt 使用函數(shù)MD5Init, MD5Update, MD5Transform。
sha2_crpyt 使用函數(shù)shaXXX_init, shaXXX_update,shaXXX_done,XXX指的是位,如512。
QNX的hash函數(shù)是按位偏移的。 Hash函數(shù)初始化之后,更新過(guò)程如下所示:
digest = update(salt), update(password) * rounds, update(password)
***一次輪數(shù)置為0時(shí),是使用密碼來(lái)更新hash函數(shù)的。 所以摘要被計(jì)算出來(lái)的時(shí)候,1000輪的設(shè)置,其實(shí)是被計(jì)算了1001輪。 除此之外,其他都是標(biāo)準(zhǔn)的。
QNX 密碼hash值爆破
John the Ripper (即使用了jumbo補(bǔ)丁)和其他通用的工具都不支持QNX shadowed密碼的hash格式。
我嘗試用python的hashlib和passlib模塊重新實(shí)現(xiàn)hash函數(shù)的邏輯。但是我得到的輸出跟/usr/bin/passwd產(chǎn)生的二進(jìn)制結(jié)果無(wú)法匹配。 所用方法的實(shí)現(xiàn)都是一致的,所以我意識(shí)到QNX的hash函數(shù)有一些特有的實(shí)現(xiàn)。這是QNX自己實(shí)現(xiàn)的代碼,并不依賴于通用的擴(kuò)展庫(kù), 比如OpenSSL。
我并不是加密專家所以我并沒(méi)有花很多的時(shí)間去逆向hash函數(shù),但是我看了SHA-2的參考文檔并且似乎QNX就是按照這個(gè)方案來(lái)實(shí)現(xiàn)的。輸出的不同可能是由于他們內(nèi)部實(shí)現(xiàn)的一個(gè)奇怪的調(diào)整導(dǎo)致的。
如果你想暴力破解hash值,你可以直接在GDB調(diào)試中調(diào)用它。另一個(gè)優(yōu)雅的實(shí)現(xiàn)就是使用dlopen(3) 和dlsym(3)去從C的封裝調(diào)用這個(gè)函數(shù)。
Breakpoint 1, 0x080493c1 in main () (gdb) call sha2_crypt(512, "password", "abcd1234abcd1234", "1000") $1 = 134559360 (gdb) x/s $1 0x8053680 : "@S@1030f372de34b8caac99b481d81ad9b57b923b385edcd3ed84f6721192f5238f34aba739e1d124919bd85c8efe13948593a6b691d8b41c1be5bc9b3906577f5d@abcd1234abcd1234"
參考資料:
[1] The Pentesting QNX Neutrino RTOS blog post from FishNet Security was the best information I could find on QNX for security assessments or penetration tests.
[2] The defaults can be found from the /usr/bin/passwd binary itself or in the online QNX development references.
[3] The qnx_decrypt.c code updated by SilentDream is the best reference for understanding QNX crypt hashes.






















