## 首頁(其他picoCTF writeup) https://hackmd.io/@sunfrancis12/ry_LLAgp3 作者: [台中教育大學 白帽社](https://hackmd.io/@ntcuhack/index) -sunfrancis12 ## Client-side-again ![](https://hackmd.io/_uploads/r19d7Mja3.png) 進來網頁,f12後看到一行超長的js ``` <script type="text/javascript"> var _0x5a46=['f49bf}','_again_e','this','Password\x20Verified','Incorrect\x20password','getElementById','value','substring','picoCTF{','not_this'];(function(_0x4bd822,_0x2bd6f7){var _0xb4bdb3=function(_0x1d68f6){while(--_0x1d68f6){_0x4bd822['push'](_0x4bd822['shift']());}};_0xb4bdb3(++_0x2bd6f7);}(_0x5a46,0x1b3));var _0x4b5b=function(_0x2d8f05,_0x4b81bb){_0x2d8f05=_0x2d8f05-0x0;var _0x4d74cb=_0x5a46[_0x2d8f05];return _0x4d74cb;};function verify(){checkpass=document[_0x4b5b('0x0')]('pass')[_0x4b5b('0x1')];split=0x4;if(checkpass[_0x4b5b('0x2')](0x0,split*0x2)==_0x4b5b('0x3')){if(checkpass[_0x4b5b('0x2')](0x7,0x9)=='{n'){if(checkpass[_0x4b5b('0x2')](split*0x2,split*0x2*0x2)==_0x4b5b('0x4')){if(checkpass[_0x4b5b('0x2')](0x3,0x6)=='oCT'){if(checkpass[_0x4b5b('0x2')](split*0x3*0x2,split*0x4*0x2)==_0x4b5b('0x5')){if(checkpass['substring'](0x6,0xb)=='F{not'){if(checkpass[_0x4b5b('0x2')](split*0x2*0x2,split*0x3*0x2)==_0x4b5b('0x6')){if(checkpass[_0x4b5b('0x2')](0xc,0x10)==_0x4b5b('0x7')){alert(_0x4b5b('0x8'));}}}}}}}}else{alert(_0x4b5b('0x9'));}} </script> ``` 為了增加程式可讀性,我們丟到[jsnice](http://jsnice.org/)裡面讓他幫我們自動整理,整理後結果如下 ``` 'use strict'; /** @type {!Array} */ var _0x5a46 = ["f49bf}", "_again_e", "this", "Password Verified", "Incorrect password", "getElementById", "value", "substring", "picoCTF{", "not_this"]; (function(data, i) { /** * @param {number} isLE * @return {undefined} */ var write = function(isLE) { for (; --isLE;) { data["push"](data["shift"]()); } }; write(++i); })(_0x5a46, 435); /** * @param {string} level * @param {?} ai_test * @return {?} */ var _0x4b5b = function(level, ai_test) { /** @type {number} */ level = level - 0; var rowsOfColumns = _0x5a46[level]; return rowsOfColumns; }; /** * @return {undefined} */ function verify() { checkpass = document[_0x4b5b("0x0")]("pass")[_0x4b5b("0x1")]; /** @type {number} */ split = 4; if (checkpass[_0x4b5b("0x2")](0, split * 2) == _0x4b5b("0x3")) { if (checkpass[_0x4b5b("0x2")](7, 9) == "{n") { if (checkpass[_0x4b5b("0x2")](split * 2, split * 2 * 2) == _0x4b5b("0x4")) { if (checkpass[_0x4b5b("0x2")](3, 6) == "oCT") { if (checkpass[_0x4b5b("0x2")](split * 3 * 2, split * 4 * 2) == _0x4b5b("0x5")) { if (checkpass["substring"](6, 11) == "F{not") { if (checkpass[_0x4b5b("0x2")](split * 2 * 2, split * 3 * 2) == _0x4b5b("0x6")) { if (checkpass[_0x4b5b("0x2")](12, 16) == _0x4b5b("0x7")) { alert(_0x4b5b("0x8")); } } } } } } } } else { alert(_0x4b5b("0x9")); } } ; ``` 但是網頁作者為了不讓我們看懂程式碼,將變數名稱經過編碼,我們要做的事情就是將這些變數名稱還原 我的作法如下: 打開[JS bin](https://jsbin.com/patalokoxe/edit?js,console,output) (也可以用google f12內建的console) 將程式輸入console(註解記得拿掉),按下enter,會輸出undefined結果 ![](https://hackmd.io/_uploads/S1Lduzj63.png) 圖片文字內容如下: ``` > var _0x5a46 = ["f49bf}", "_again_e", "this", "Password Verified", "Incorrect password", "getElementById", "value", "substring", "picoCTF{", "not_this"]; (function(data, i) { var write = function(isLE) { for (; --isLE;) { data["push"](data["shift"]()); } }; write(++i); })(_0x5a46, 435); var _0x4b5b = function(level, ai_test) { level = level - 0; var rowsOfColumns = _0x5a46[level]; return rowsOfColumns; }; function verify() { checkpass = document[_0x4b5b("0x0")]("pass")[_0x4b5b("0x1")]; split = 4; if (checkpass[_0x4b5b("0x2")](0, split * 2) == _0x4b5b("0x3")) { if (checkpass[_0x4b5b("0x2")](7, 9) == "{n") { if (checkpass[_0x4b5b("0x2")](split * 2, split * 2 * 2) == _0x4b5b("0x4")) { if (checkpass[_0x4b5b("0x2")](3, 6) == "oCT") { if (checkpass[_0x4b5b("0x2")](split * 3 * 2, split * 4 * 2) == _0x4b5b("0x5")) { if (checkpass["substring"](6, 11) == "F{not") { if (checkpass[_0x4b5b("0x2")](split * 2 * 2, split * 3 * 2) == _0x4b5b("0x6")) { if (checkpass[_0x4b5b("0x2")](12, 16) == _0x4b5b("0x7")) { alert(_0x4b5b("0x8")); } } } } } } } } else { alert(_0x4b5b("0x9")); } } ; ========= > undefined ``` 之後將一個個經過編碼的變數輸入至console,就可以看到他經過編碼前的樣子,我們在做的事情就是把程式碼還原成人類看的懂的模樣 ![](https://hackmd.io/_uploads/SyBLczoa2.png) 我們要將我們反組譯後的變數寫回去程式,這裡我會推薦使用vscode,可以利用vscode的`變更所有發生次數`,`Change all occurrences`來一次改寫大量變數 *備註:由於是mkv轉gif,導致有一些網格紋路* ![](https://i.imgur.com/bGu6EFH.gif) 整理完後,程式碼如下 ``` function verify() { checkpass = document["getElementById"]("pass")["value"]; /** @type {number} */ split = 4; if (checkpass["substring"](0, split * 2) == "picoCTF{") { if (checkpass["substring"](7, 9) == "{n") { if (checkpass["substring"](split * 2, split * 2 * 2) == "not_this") { if (checkpass["substring"](3, 6) == "oCT") { if (checkpass["substring"](split * 3 * 2, split * 4 * 2) == "f49bf}") { if (checkpass["substring"](6, 11) == "F{not") { if (checkpass["substring"](split * 2 * 2, split * 3 * 2) == "_again_e") { if (checkpass["substring"](12, 16) == "this") { alert("Password Verified"); } } } } } } } } else { alert("Incorrect password"); } } ; ``` [substring()](https://www.fooish.com/javascript/string/substring.html)的是一種查詢的function() ``` var str = "abcdefg" console.log(str.substring(0,3)) ##輸出 abcd console.log(substring(4,6)) ##輸出 ef ``` 最後得到結果 ``` picoCTF{not_this_again_ef49bf} ```