進去後發現就一個輸入框,提示我們輸入flag{}
不過輸了後沒反應,那麼審查元素看看
可以發現是調用的ctfshow()這個函數
在chrome的console窗口調試下這個函數看下它幹嘛的
格式化下代碼方便審計
可以發現這是把js代碼變量名16進制編碼後再把代碼邏輯複雜化
好我們來讀下這串代碼:
首先定義一個變量_0x4d832a
值爲一個字典{}
字典裏有一個鍵值對
鍵爲'aTkul'
值爲一個函數,其作用就是把傳來的值return回這個值的函數
用人話來講就是調用一個函數
到下面這串_0x4d832a[a0_0x138e('0x5')](我們);
就是一個字典調用,啥你問a0_0x138e('0x5')是啥??
問console
ok到這先好好理解上面這串最簡單的加密邏輯,因爲後面這整個js都是這玩意
js指的就是這玩意,套着script的皮卻是css的後綴,佛了
理解完後就可以往下跟進了
也就是跟進我們()這個函數
因爲壓縮過就只能把全部js全複製出來格式化,當然你想手工提取出來也行(有更好的方法請在評論說出來,感謝各位師傅了)
ok跟進到這如果理解清楚上面說的,那麼就能很清楚第一行就是定義一個字典
裏面的值先不細看
往下看是一堆變量,然後到一個判斷
那麼從判斷開始一步一步往上推
兩個值
_0x491b2b=調用_0xd8e338['UIVfT']這個函數,傳遞的值爲getEncodeString,_0x35b4d3[a0_0x138e('0xa')(0x0, 0xd)
這裏有三個函數,第二個看名字就知道幹啥的就不跟進了
第一個就是調用上面字典的UIVft值
就是把傳進來第二個的值當作第一個值的實參
人話講就是getEncodeString(_0x35b4d3[a0_0x138e('0xa')](0x0, 0xd))
ok那看最後一個函數,先把16進制轉成10(方便看)
getEncodeString(_0x35b4d3[a0_0x138e('10')](0, 13))
接着看a0_0x138e('10')這個是啥就行了
放到console
getEncodeString(_0x35b4d3.substr(0, 13))
這意思很明顯了,繼續往上找_0x35b4d3這個變量
跟上面用的一樣的方法a0_0x138e('0xa')也就是調用substr函數
繼續找_0x1f7275
反轉字符串_0x1ef9ff,繼續
把兩個參數相加
這兩個參數等於
很明顯就是把getEncodeString(_0x6ab3ec)+hex_md5(_0x6ab3ec)
那麼重要的就是搞清楚這個_0x6ab3ec是啥
也就是說獲取頁面輸入的getEncodeString(reverseStr(flag再進行兩段加密之和))
邏輯很清楚了,就是把我們輸入的flag和flag進行比較
那麼我們找到比較的這個變量就ok啦
和上面一樣的審計方式
加密後的flag找到!
那麼按照我們輸入的加密邏輯逆過來就能解密了
getEncodeString(reverseStr("2xsrn72z4wurn7k5ewp5nx3x6wqjm72z4wxbn33zcgwzm"))
就差最後一步了getEncodeString("mzwgcz33nbxw4z27mjqw6x3xn5pwe5k7nruw4z27nrsx2")
因爲這是Encode的函數,所以得跟進去看怎麼加密(出題人沒給Decode,當時看到這一大串.以爲要自己手寫,心態蹦了...)
我們可以試試用這函數加密看得到的密文是怎樣的
什麼!!?竟然是mzwgczy,
S這不就是base32嗎!!!
......好了不裝了老實分析下getEncodeString吧
好了我分析完了發現是base32加密
你呢?
最後解密就得到flag啦