23柏鷺杯-misc

WXjzc發表於2024-06-05

我記得比賽的時候,misc都是0解。

怎麼不算另類的1血呢?

help_me實在不會,arm看不了一點

消失的鑰匙

先看驗證邏輯,能夠看到generateZipPassworddecryptFlag這兩個方法內容不見了

截圖

透過在apk中尋找半年,找到一個時間不對的classes3.dex,檢視hex發現是gz壓縮

截圖

截圖

匯出解壓一下,拿到了一半的dex

截圖

再根據時間線索,找到另一個檔案

截圖

截圖

將兩個檔案合併,得到完整的dex

截圖

getPackageSignature這個方法hook一下,拿到了返回值748124a9239a8f2d79a0de294fbba042

Java.perform(function () {
    Java.choose('com.example.test.MainActivity',{
        onMatch: function(instance){
            console.log(instance.getPackageSignature())
        },
        onComplete: function(){}
    })
})

截圖

這裡可以確定748124a9239a8f2d79a0de294fbba042是key,com.example.test的MD5取前16位是iv

截圖

截圖

最後密碼是對包名後16位進行aes加密,取16-48位,即231287ee4876a3fed4a34bac962d513e

截圖

之後解密

截圖

採用fridahook的方式,來直接模擬執行其中的方法

Java.perform(function () {
	Java.choose('com.example.test.MainActivity', {
		onMatch: function (instance) {
			var pwd = '231287ee4876a3fed4a34bac962d513e'
			var zipContent = instance.zipDecrypt(pwd)
			let Flag = Java.use("com.example.test.FlagOuterClass$Flag").$new();
			let flagContent = Flag.parseFrom(zipContent)
			var key = flagContent.getKey()
			var iv = flagContent.getIv()
			var keyString = Java.use('java.lang.String').$new(key) //轉成Java中的String,來獲得getBytes方法
			var ivString = Java.use('java.lang.String').$new(iv)
			let AESUitls = Java.use('com.example.test.AESUtils').$new(keyString.getBytes(),ivString.getBytes())
			console.log(AESUitls.decrypt(flagContent.getFlag(),true))
		},
		onComplete: function () { }
	})
})

截圖

最後的flag為flag{ISEC-C4n_U_f1nd_th3_10st_2Ip_p455Word}

截圖

程式碼吞噬者(尋找病毒進化的密碼)

這題好像是當時平臺答案不對,導致0解

透過反射載入decode.dex,執行程式碼

截圖

loadKey中再次反射

截圖

在patch目錄下處理dxdiff,但是該檔案不會被保留

截圖

截圖

考慮到dxdiff已經載入到記憶體,因此直接dump

截圖

拿到了程式碼

截圖

根據對password的判斷,拿到了輸入的明文

_dict = "9>AG3OCP1N2-4L5K6M7+BQD&EVF=0@8$"
password = '+>M=+K-@MN+-MK-@MN++MK+OM=M&MK'
for i in range(len(_dict)-1,-1,-2):
    c2 = _dict[i]
    c1 = _dict[i-1]
    password = password.replace(c2,c1)
print(bytes.fromhex(password))
# you are awesome

截圖


讀取了DIFF_HEX,又進行了一次更新

截圖

截圖

但是在更新之前,將update_1_.dex刪除了

截圖

因此對delete進行hook,直接阻止刪除

Java.perform(function () {
	let File = Java.use("java.io.File");
	File["delete"].implementation = function () {
		return 0
	};
});

截圖

本質上就是對解密後的dict和diff進行md5計算

截圖