Bugku-CTF:學會如來神掌應該就能打敗他了吧

題目地址:http://123.206.31.85:1616/

老師傅說過拿這類到題目要先正常流程走一遍,要先對它有大概的認識

所以既然是遊戲我們就得先看看它怎麼玩的

.......

別說還挺好玩,不過幹回正事

首先整理流程:

結合題目:學會如來神掌應該就能打敗他了吧

和開始頁面的介紹:不知是誰傳出來的,只要學了這如來神掌,就可以打敗蒙老魔,還天下一個太平。故事就至此開始了..

可以發現遊戲的目標就是學會如來神掌然後打敗濛濛老魔

目標有了就可以下一步啦,

進入遊戲第一步審查元素,是否源碼泄露(無發現),和目錄掃描

可以發現有頭部的js 文件和內容確認初始化屬性的php頁面

你可能跟我一樣看到php就各種嘗試,一頓攻擊後可以猜測這後面的值是確定遊戲流程的,start開始,map確定,再試下可能存在的頁面時發現給我們跳轉到了這個123.206.31.85:1616/wulin.php

是不是和我一樣臉上揚起了笑容,有輸入框而且是判斷flag的,不過還是開心太早,一頓操作後都沒任何反應(可能是我太菜沒能攻擊成功),審查元素也沒任何有用的信息

還是老老實實玩吧,確定屬性後我們能做的就是練功和賺錢,

到這沒線索了,那就回到一開始的js文件出發

script.js是eval(function)加密過的

網上找解密源碼後可以得到(https://www.cnblogs.com/zs-note/p/3895500.html)

可以發現的確只要打了boss就會出flag,那就往上依次找到key→ca→mingwen→temp→temp_name→"user"

從getCookie(temp_name)入手:

可以發現這個就是返回cookie的,通過burp抓包後發現,這人物的狀態就是靠cookie保存的,那麼我們只要能解密這cookie不就可以僞造cookie了,新目標get!

接下來是decodeURIComponent(temp),這js內置函數對URI解碼

解碼後傳到decode_create(temp),審計代碼:

new Base64();創建一個Base64對象,也就是一開始得到js文件的base64.js

decode傳進來的temp

再挨個得到ASCII後按位異或i,

接着把得到的數-((i % 10) + 2),

最後在轉回字符。

ok我們把代碼拉下來把cookie傳進去看看能得到什麼

O:5:"human":10:{s:8:"xueliang";i:988;s:5:"neili";i:882;s:5:"lidao";i:70;s:6:"dingli";i:72;s:7:"waigong";i:0;s:7:"neigong";i:0;s:7:"jingyan";i:0;s:6:"yelian";i:0;s:5:"money";i:0;s:4:"flag";s:1:"0";}

得到一串序列化字符串,看到這些拼音,臉上露出了微妙的微笑

雖然看到flag但是是空的所以MD5(key)必然沒值,還是得打boss拿

那麼馬上屬性拉滿,然後再倒過來走一遍這些流程加密就完事啦

ok倒過來看上面解密的步驟就是:

encode_create(temp):

new Base64();創建一個Base64對象,也就是一開始得到js文件的base64.js

把得到的數-((i % 10) + 2),

再挨個得到ASCII後按位異或i,

轉回字符

encode傳進來的temp

接下來是encodeURIComponent(temp)

就ok啦

編寫代碼:

先把base64.js的代碼copy過來

出題人還是挺善良的給了encode,但他竟然在這挖坑,害我在這看好久,差點就自己重寫了,好險沒這本事...

對比可以發現encode一開始是做了_utf8_encode的,而decode這一段是註釋掉的(太過分了)所以把這句刪掉接着

最後

完成

完整代碼

<script>
	function Base64() {
 
	// private property
	_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
 
	// public method for encoding
	this.encode = function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
		while (i < input.length) {
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
			output = output 
			+ _keyStr.charAt(enc1) 
			+ _keyStr.charAt(enc2) 
			+ _keyStr.charAt(enc3) 
			+ _keyStr.charAt(enc4);
		}
		return output;
	}
 
	// public method for decoding
	this.decode = function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
		while (i < input.length) {
			enc1 = _keyStr.indexOf(input.charAt(i++));
			enc2 = _keyStr.indexOf(input.charAt(i++));
			enc3 = _keyStr.indexOf(input.charAt(i++));
			enc4 = _keyStr.indexOf(input.charAt(i++));
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
			output = output + String.fromCharCode(chr1);
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
		}
		//output = _utf8_decode(output);
		return output;
	}
 
	// private method for UTF-8 encoding
	_utf8_encode = function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
		for (var n = 0; n < string.length; n++) {
			var c = string.charCodeAt(n);
			if (c < 128) {
				utftext += String.fromCharCode(c);
			} else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			} else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
		return utftext;
	}
 
	// private method for UTF-8 decoding
	_utf8_decode = function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
		while ( i < utftext.length ) {
			c = utftext.charCodeAt(i);
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			} else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			} else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		}
		return string;
	}
}
function getCookie(cname) {
    var name = cname + "=";
    var ca = "user=UTw7PCxqe3FjcC42OThOjWtSUFYwbm99amlzbG0wI3MeHxwcZ1liZxQMWEFDXl8EdUUOCAgCd016B34WUlFWWTVoATEAB3R5P3Z2CmYgPTY5Pj90FSUUF2QfL2ZnYnYhCRMTGRQPQCcHKFIvEShXUlYCGQMbDQ4FXEcXREo%2FBTzBxKbu6fbrB%2BH%2Bps3nsLrP6dCs0LgR8fj1%2F%2B6y3%2B%2FapJ3XnJnkjNPf0NnRjpPD7pjzzfaMiJDcxt%2FXkP%2FB%2BI2C5vTqgUE%3D".split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i].trim();
        if (c.indexOf(name) == 0) return c.substring(name.length, c.length)
    }
    return ""
}
function decode_create(temp) {
    var base = new Base64();
    var result = base.decode(temp);
    var result3 = "";
    for (i = 0; i < result.length; i++) {
        var num = result[i].charCodeAt();
        num = num ^ i;
        num = num - ((i % 10) + 2);
        result3 += String.fromCharCode(num)
    }
    return result3
}
function encode_create(temp) {
    var base = new Base64();
    var result = temp;
    var result3 = "";
    for (i = 0; i < result.length; i++) {
        var num = result[i].charCodeAt();
        num = num + ((i % 10) + 2);
        num = num ^ i;     
        result3 += String.fromCharCode(num)
    }
    result3 = base.encode(result3);
    return result3
}
#密文解密
var temp = getCookie("user");
temp1 = decodeURIComponent(temp);
var mingwen = decode_create(temp1);
console.log(mingwen);

#明文加密
var temp2 = encode_create('O:5:"human":10:{s:8:"xueliang";i:9999999;s:5:"neili";i:9999999;s:5:"lidao";i:9999999;s:6:"dingli";i:9999999;s:7:"waigong";i:9999999;s:7:"neigong";i:9999999;s:7:"jingyan";i:9999999;s:6:"yelian";i:9999999;s:5:"money";i:9999999;s:4:"flag";s:1:"0";}');
var miwen = encodeURIComponent(temp2);
console.log(miwen);




</script>

 

全部99999後會發現

那不行,因爲不知道屬性上限是多少,那就改錢把,因爲商店的書籍金額都比較大所有應該不會有太大問題

金額全部99999,你可能發現了這樣每做一次操作就得改一次包豈不是很麻煩

別忘了還有個練功和賺錢,都是通過傳進來的值在這基礎上增加的,練功放棄了,那就走賺錢吧

好了到這基本完成了,買完商店的書籍學瞭如來神掌後去打boss,打贏後會彈窗出flag,不過提示我們不知道真假

這時別忘了一開始還有個彩蛋頁面來驗證flag的,輸入後會發現有限制,直接右鍵檢查去掉輸入框的長度限制

回車

-----------------------------------------------------------------我是分割線--------------------------------------------------------------

 

看完了覺得不錯就點個贊或者評論下吧,感謝!!!

如果本文哪裏有誤隨時可以提出了,收到會盡快更正的

發佈了5 篇原創文章 · 獲贊 13 · 訪問量 4184
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章