2021年8月25日 星期三

[macOS] 使用 hashcat 驗證/回憶 iOS iPhone/iPad iTunes 備份檔 密碼

故事起源於幫長輩換手機,這時手機有用過 itunes 備份過一份並且加密,但...怎麼都想不起密碼。在網路上找尋解法時,大概可以看到幾款破解軟體(推論是免費試用,真正要破解時需加價)。此刻的不方便,反而要感謝起 Apple 資安服務,高規格保護資料!大家的破解原理都是一樣的:暴力解-猜密碼。

研究後,發現有個 hashcat 的 open source 統包了眾多加密系統的猜密碼任務,而網路上 2017年也以人講解使用過程,還滿仔細的:

Crack Encrypted iOS backups with Hashcat

筆記一下過程:
  1. 先找到 iOS 備份檔擺放的位置: https://support.apple.com/en-us/HT204215
    • macOS: ~/Library/Application Support/MobileSync/Backup/
  2. 備份都是目錄結構,找到目錄中的 Manifest.plist 檔案
  3. 依照裡頭的資訊,準備餵給 hashcat 的資料,可分成 iOS 10 以上跟 iOS 9 以前,組成 inputFromManifest.txt 資料
    • Less then iOS 10:
      • $itunes_backup$*<ver>*<WPKY>*<ITER>*<SALT>**
    • iOS 10 or later:
      • $itunes_backup$*<ver>*<WPKY>*<ITER>*<SALT>*<DPIC>*<DPSL>
如此,就可以靠 hashcat 來運算,其原理包括支援平行處理(GPU)去算出密碼,包括從字典檔、暴力猜等等的。此外,關於上述 2~3 步驟,其實也有人佛心提供工具:github.com/philsmd/itunes_backup2hashcat,透過 perl 小程式自動幫人從 Manifest.plist 組出資訊:

% perl itunes_backup2hashcat.pl yourBackupDir/Manifest.plist 
$itunes_backup$*10*#######*####*######*######*##################
% perl itunes_backup2hashcat.pl yourBackupDir/Manifest.plist > inputFromManifest.txt

後續就著重 hashcat 的指令筆記,若要更多指令資訊,逛個官方網站是最方便的:hashcat.net/wiki/doku.php?id=hashcat

以在 https://www.youtube.com/watch?v=MMySnPzsPYU 內提供的範例資訊:

% cat inputFromManifest.txt 
$itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76be166232b4a01bd6974abb27c39034993591c15ba03a14e3b*10000*0ca3ccfc453b32f9ca9aceb754b87f4e0ab9cb95*10000000*bdee6869caa7999e9576f390a248a29f38d10d6f

這時都是 iOS 10 的密碼,因此在使用 hashcat 會採用 -m 148000 參數。若是 iOS 9 以前,要用 -m 14700 參數這些都有定義在官方網站的 wiki 中。

第一招:暴力解,此例猜4個數字:

% hashcat -d 1 -m 14800 ./inputFromManifest.txt -a 3 '?d?d?d?d'
hashcat (v6.2.3) starting

OpenCL API (OpenCL 1.2 (Jun 17 2021 15:24:17)) - Platform #1 [Apple]
====================================================================
* Device #1: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz, 16320/16384 MB (4096 MB allocatable), 4MCU
* Device #2: Intel(R) Iris(TM) Plus Graphics 640, skipped

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates

Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt
* Brute-Force
* Slow-Hash-SIMD-LOOP
* (null)

Watchdog: Temperature abort trigger set to 100c

Host memory required for this attack: 1 MB

[s]tatus [p]ause [b]ypass [c]heckpoint [f]inish [q]uit => 

這時隨時都可以按 s 去看暴力解的進度:

Session..........: hashcat
Status...........: Running
Hash.Name........: iTunes backup >= 10.0
Hash.Target......: $itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76b...d10d6f
Time.Started.....: Wed Aug 25 20:37:03 2021 (6 mins, 50 secs)
Time.Estimated...: Wed Aug 25 23:30:00 2021 (2 hours, 46 mins)
Kernel.Feature...: Pure Kernel
Guess.Mask.......: ?d?d?d?d [4]
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:        1 H/s (13.34ms) @ Accel:128 Loops:256 Thr:1 Vec:4
Recovered........: 0/1 (0.00%) Digests
Progress.........: 0/10000 (0.00%)
Rejected.........: 0/0 (0.00%)
Restore.Point....: 0/1000 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:8056320-8056576
Candidate.Engine.: Device Generator
Candidates.#1....: 1234 -> 1124
Hardware.Mon.SMC.: Fan0: 100%
Hardware.Mon.#1..: Temp: 66c

[s]tatus [p]ause [b]ypass [c]heckpoint [f]inish [q]uit => 

而幸運解出密碼時,會顯示以下資訊,主要是 Status 會顯示 Cracked 而密碼則是紀錄在冒號後面 (:1234)

$itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76be166232b4a01bd6974abb27c39034993591c15ba03a14e3b*10000*0ca3ccfc453b32f9ca9aceb754b87f4e0ab9cb95*10000000*bdee6869caa7999e9576f390a248a29f38d10d6f:1234
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Name........: iTunes backup >= 10.0
Hash.Target......: $itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76b...d10d6f
Time.Started.....: Wed Aug 25 20:37:03 2021 (8 mins, 26 secs)
Time.Estimated...: Wed Aug 25 20:45:29 2021 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Mask.......: ?d?d?d?d [4]
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:        1 H/s (11.09ms) @ Accel:128 Loops:256 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests
Progress.........: 512/10000 (5.12%)
Rejected.........: 0/512 (0.00%)
Restore.Point....: 0/1000 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:9984-9999
Candidate.Engine.: Device Generator
Candidates.#1....: 1234 -> 1124
Hardware.Mon.SMC.: Fan0: 100%
Hardware.Mon.#1..: Temp: 65c

Started: Wed Aug 25 20:36:57 2021
Stopped: Wed Aug 25 20:45:30 2021

第二招:將可能的密碼寫在 myPasswordlist.txt 中去驗證,指令:

% cat myPasswords.txt 
5678
09876
1234

% hashcat -d 1 -m 14800 ./inputFromManifest.txt ./myPasswords.txt 
hashcat (v6.2.3) starting

OpenCL API (OpenCL 1.2 (Jun 17 2021 15:24:17)) - Platform #1 [Apple]
====================================================================
* Device #1: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz, 16320/16384 MB (4096 MB allocatable), 4MCU
* Device #2: Intel(R) Iris(TM) Plus Graphics 640, skipped

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt
* Slow-Hash-SIMD-LOOP
* (null)

Watchdog: Temperature abort trigger set to 100c

Host memory required for this attack: 1 MB

Dictionary cache built:
* Filename..: ./myPasswords.txt
* Passwords.: 3
* Bytes.....: 16
* Keyspace..: 3
* Runtime...: 0 secs

The wordlist or mask that you are using is too small.     
This means that hashcat cannot use the full parallel power of your device(s).
Unless you supply more work, your cracking speed will drop.
For tips on supplying more work, see: https://hashcat.net/faq/morework

Approaching final keyspace - workload adjusted.           

$itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76be166232b4a01bd6974abb27c39034993591c15ba03a14e3b*10000*0ca3ccfc453b32f9ca9aceb754b87f4e0ab9cb95*10000000*bdee6869caa7999e9576f390a248a29f38d10d6f:1234
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Name........: iTunes backup >= 10.0
Hash.Target......: $itunes_backup$*10*c8c96e8d6175f1356da6dcf5791ad76b...d10d6f
Time.Started.....: Wed Aug 25 20:52:58 2021 (10 secs)
Time.Estimated...: Wed Aug 25 20:53:08 2021 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (./myPasswords.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:        0 H/s (0.18ms) @ Accel:128 Loops:256 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests
Progress.........: 3/3 (100.00%)
Rejected.........: 0/3 (0.00%)
Restore.Point....: 0/3 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:9984-9999
Candidate.Engine.: Device Generator
Candidates.#1....: 5678 -> 1234
Hardware.Mon.SMC.: Fan0: 20%
Hardware.Mon.#1..: Temp: 58c

...

大概就這兩招筆記一下,未來忘記密碼時,就可以靠 hashcat 幫忙批次測試記憶中的密碼了

2021年7月20日 星期二

Node.js 筆記 - 使用 Puppeteer 進行 JS Injection 與 Custom function 定義實作 @ Puppeteer v10, Node.js v16.5.0

之前使用 Puppeteer 方便自己撰寫一些監控 http requests ,像是即時監控 remote resource 變化。接著,要來把玩 JS Injection。

如果使用 Puppeteer 的用法是包括持續瀏覽網頁的話,那適合在網頁 onload 的情況下植入:

// https://pptr.dev/#?product=Puppeteer&version=v10.0.0&show=api-event-domcontentloaded
// https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
//
// The load event is fired when the whole page has loaded, including all dependent resources such as stylesheets and images. This is in contrast to DOMContentLoaded, which is fired as soon as the page DOM has been loaded, without waiting for resources to finish loading.
//
page.on('load', async () => {
console.log('on.load');
});

如果是瀏覽網頁後,立馬植入 JS Code 運行並且任務就結束了,那就是適合在 network 連線閒置後處理:

await page.goto(target_url, {
waitUntil: 'networkidle0',
});
console.log('networkidle0');

而 JS Injection 的方式:

await page.evaluate((js_code) => {return Promise.resolve(window.eval(js_code));}, js_resource_content);

其中 js_resource_content 就是預計植入的 JS Code 字串。例如有多份程式碼要植入,可以跑回圈:

for(let i=0 ; i<js_resource.length ; ++i) {
console.log('inject: '+js_resource[i]+', size: '+js_resource_content[i].length);
await page.evaluate((js_code) => {return Promise.resolve(window.eval(js_code));}, js_resource_content[i]);
}

其中 js_resource[] 紀錄的是 js code 網址,而 js_resource_content[] 是紀錄該 js code 網址的內容。

最後,提一下自訂函數的寫法:

// https://github.com/puppeteer/puppeteer/blob/main/examples/custom-event.js
// Define a window._puppeteer_helper function on the page.
await page.exposeFunction('_puppeteer_helper', (data) => {
console.log(`_puppeteer_helper fired`);
});

如此,又可以靠 JS Injection 去呼叫 window._puppeteer_helper ,或是靠 phage.evaluate 執行了:

let result = await page.evaluate((data_to_page) => {
let data = data_to_page;
return Promise.resolve(window.eval(`
window._puppeteer_helper();
`));
}, 'nothing');

2021年7月14日 星期三

XBOX 遊戲目錄 6歲以下 幼兒遊戲清單 @ XBox One S

當年買 XBOX ONE S 時,想說花五千左右買來當 藍光DVD播放器 的,結果...不小心就再加碼了停產的 Kinect 感應器、連接線,接著又入坑買了些體感的遊戲,像是首選目標是 Just Dance 以及 Kinect 運動大會:對抗賽 ,事實證明,果真該先查遊戲品價再買 XD Kinect 運動大會 似乎鳥掉不少,玩起來滿常跟感應狀態不順,大概只有玩網球跟保齡球比較順吧。不過 Just Dance 的體驗滿讚的,堪稱完美的體感互動。

近一年半,因為台灣疫情的關係,開始在 XBox.com 較大筆的消費買了不少遊戲,當時以直在想 XBox Store 裡一堆 18禁 血腥遊戲,還真不知該買什麼遊戲給小孩,之後在網路上找了一下,找到不少人推薦樂高的遊戲,入門款:樂高玩電影 LEGO THE MOVIE VIDEOGAME,趁著 XBox Store 特價時候,入手小試身手。以下的遊戲就偏向把手遊戲,對於 Kinect 體感就停留在 Just Dance 才會打開來用了。

先提使用 XBox Store 就是買數位版遊戲心得,好處:
  • 不定期會有大幅度的特價
  • 購買不用等實體光碟片寄到家
  • 不用擔心 XBOX 遊樂器哪天開始挑片
缺點:
  • 遊戲很大時,要等下載很花時間,家裡網速不快時,都可能會等上數小時才能下載完畢(20GB 遊戲大小,每秒 10MB/s 下載,要花 35分鐘)
  • 遊戲不玩時,不像實體遊戲片可以在二手市場交易,之前買的 Just Dance 2018 是實體光碟片,想玩買新的一代時,就把舊的在二手市場賣了,可以回收一半以上還滿不錯的(買一千多賣六七百)。
接著來聊聊樂高遊戲了!請留意,樂高遊戲,某個角度上還是帶有暴力意識,分級來說都是建議12歲以上的小孩的,例如要打掉建築物、打壞人等等,只是 XBOX 上太少幼兒把玩的遊戲,就試著引導他們當作解題遊戲。若很在意分級設計,還是避開比較安心。

買樂高遊戲還有個重點:可以兩人一起玩的。

小孩第一次接觸樂高遊戲,在看不懂文字上果真難上手,需要大人陪著,但大概撐過去後,便開始感受到遊戲有趣的點:解題、尋找成就感。雖然他們根本連劇情都不懂,也不懂樂高音樂以及出場的角色們,但小孩很會腦補,就像玩扮家家酒那樣。看著小孩這樣兩週玩著這款玩到幾乎破關,覺得滿驚訝的。大概一天玩 2 小時左右。有些場景因為沒有讀劇情,不懂文字上描述解題方向而卡關著,推論應該有八成都可以自己摸索,剩下兩成要去幫忙點一下。

第一次感受到長劇情遊戲帶給小孩的樂趣。回想起以前玩 PC 或 TV 遊戲時,其實很多看不懂也繼續玩,像是國小玩超任的熱血硬派也看不懂日文,一樣暑假天天玩天天練功了一個多月。(現在靠模擬器跟電腦加速玩,大概一週內就能破關)

爾後趁 XBox Store 不定期特價(感覺兩三週會有一輪樂高系列遊戲特價),就順便收購老遊戲而不是買最新不特價的遊戲,收藏了:
其中,我自己覺得 The LEGO Movie 2 Videogame 複雜度又比第一代高,就算玩過第一代也不一定能上手,因為複雜度上更重文字的描述,像是要建制對應的東西,選單更加複雜,可能將近要花 50% 時間帶小孩玩,相較之下還是 The LEGO Movie Videogame 適合學齡前小孩把玩,算是致敬第一代才收藏 XD 整體上其實可以不用花錢買它的,他比較偏給青少年玩的遊戲。

依序嘗試了 The LEGO Movie Videogame、The LEGO NINJAGO Movie Video Game、LEGO® CITY Undercover、The LEGO Movie 2 Videogame、LEGO Marvel Super Heroes、LEGO® The Hobbit™,感覺 NINJAGO 跟 LEGO Marvel Super Heroes還滿快上手的,其餘有的是劇情看不懂稍微複雜就卡關了。由於樂高很經典,再加上上述遊戲都稱得上老遊戲了,在網路上還滿多攻略,甚至 bilibili 還有玩家闖關的影片紀錄,若擔心不會玩,可以先查一下

此外,在 NETFLIX 上剛好有很多樂高小電影,也可以搭配播來看看,像是 NETFLIX - 樂高玩電影 2

其他推薦遊戲:
扣掉樂高後,迪士尼大冒險跟 Woodle Tree Adventures 都是很超值的遊戲!有興趣可以嘗試迪士尼大冒險,裡頭的遊戲可以玩上好一陣子。以上的價錢都是台幣。

有興趣的可以一週逛個 XBox Store 優惠區一下 https://www.xbox.com/zh-tw/games/all-games?cat=onsale ,看看有沒有想收藏的遊戲。只是,現在 Switch 當道,不需刻意為了玩這些遊戲買 XBox ,親子遊戲還是 Switch 比較多。

2021年7月7日 星期三

MacBook Pro 13吋 換喇叭揚聲器 Speaker @ A1502, Retina, 13-inch, Early 2015,

MacBook 13 A1502 Speaker

Macbook 已經用了五年多了,大概年初開始發現喇叭破音,有看到很多坊間解法,像是拆掉喇叭後,試圖找到破點,甚至塗上一點薄薄的白膠來修復,但我第一次看拆喇叭的影片,就懶了 XD

接著原本單邊正常,撐了兩三個月終於一起壞光光了... 於是乎進入藍牙小喇叭的用法,結果因為疫情關係要看個直播又要開啟藍芽喇叭,久而久之,還是覺得不方便。且不知道是不是外接喇叭久了,換了揚聲器後,反而覺得內建音效很差...耳朵被慣壞了!

就這樣...隨意找了一下,用 A1502 (自己的 MacBook 型號) 加 喇叭 或 揚聲器 這關鍵字,就可以輕鬆找到哪邊有在賣,一對大概都賣台幣 1100 以上。再加上本身就已經敗過 米家精修螺絲起子套裝組 ,這時需要的工具都備齊了。

最後就拆一下筆電,斷一下電源,在輕輕的把螺絲卸下,並且照拆除的順序再裝回去即可。不是太大的問題。

由於 Youtube 上面已經有許多教學影片,非常建議先看過一次,留意拆法,像是喇叭要拆離主機板時該怎樣做。

MacBook 13 A1502 Speaker

MacBook 13 A1502 Speaker

[Linux] 修復 Ubuntu 12.04 無法安裝軟體 - W: Failed to fetch 404 @ Ubuntu 12.04

老機器環境:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 12.04.5 LTS
Release: 12.04
Codename: precise

主要是在 server 運行 apt-get update 時,會出現一堆 404 問題:

W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/precise-backports/multiverse/binary-i386/Packages 404

追了一下應當是 12.04 已經不維護了。運氣不錯,有找到 old-releases.ubuntu.com 位置:
  • https://archive.ubuntu.com/ubuntu/
  • https://old-releases.ubuntu.com/ubuntu/
接著就動手換掉 /etc/apt/sources.lis 即可,包括來源 server 換完後,記得要再把 /var/lib/apt/lists 先移除:

$ sudo mv /var/lib/apt/lists /var/lib/apt/lists-backup
$ sudo mkdir -p /var/lib/apt/lists
$ sudo apt-get update

如此就會修復相關資訊,可以在靠 apt-get 安裝軟體了。

此外,若剛好在除錯時,刪除了已安裝過的軟體,接著做了上述後,又要安裝時,會碰到資訊對不上的問題,如:

dpkg:error processing package XXX (--configure):
subprocess installed post-installation script returned error exit status 10

解法就是清除 /var/lib/dpkg/info/ 下相關套件的資料後,重新安裝或是跑完後續流程:

$ sudo mkdir /var/lib/dpkg/info/backup
$ sudo mv /var/lib/dpkg/info/XXX* /var/lib/dpkg/info/backup/
$ sudo apt-get install -f