bugkuctf Writeup

bugkuctf:https://ctf.bugku.com

Target address: http://123.206.31.85:1616/

After entering the drone, select the character attributes you want and start the game

Insert picture description here

After looking at other game functions, we found that we need to pass the crusade and defeat the old demon to pass the level.

Insert picture description here

You can buy Tathagata Palm from the mall, but you need to use silver to buy it. Do we still have so much money to buy cheats

Insert picture description here
You can earn 100 taels every 5 seconds through the earning function

Insert picture description here
By making money, we can see that in the cookie returned to us by the server set-cookie, only one letter has changed.

Insert picture description here
Of course, we can write a python script to automatically match the setcookie of the returned package to replace our own cookie, and then swipe the money, but I calculated it, the Tathagata Palm is 100,000 silver taels, we need to swipe 1,000 times, once every 5 seconds, that’s 5000 seconds, then it will take about 1 hour to get out.

This is impractical, and then I checked the html source code and found nothing that works, but there are 3 js files.

Insert picture description here
When I clicked on script.js, I found some unusual characters, then I set the browser encoding to unicode, and the following characters were displayed.

Insert picture description here
I beautify the code with js and perform code analysis:

function getCookie(cname) {
    
    #下面函数中有一个变量user被传输进来
    var name = cname + "=";#name = "user="
    var ca = document.cookie.split(';');#以分号切割cookie,赋值到ca变量中
    for (var i = 0; i < ca.length; i++) {
    
    #有一个cookie就执行一次for循环
        var c = ca[i].trim();#trim函数为去空,将第一个cookie去空赋值c变量
        if (c.indexOf(name) == 0) # 从变量c(c就是我们的cookie)中查找字符串name(uname就是字符喜欢"user="),如果找到字符串"uname="排最前,那么就会返回0
        	return c.substring(name.length, c.length)
        	# c.length(为cookie的长度) name的长度为字符串"user="的长度
        	# 返回cookie里等号及以后的内容
    }
    return "" #否则返回空
}# 这个函数就是截取cookie中user变量中的内容

function decode_create(temp) {
    
    #temp为url解码后的cookie
    var base = new Base64();#实例化base64到base变量中
    var result = base.decode(temp);# base64解码temp变量(temp为cookie)
    var result3 = "";
    for (i = 0; i < result.length; i++) {
    
    
        var num = result[i].charCodeAt();#返回字符串 Unicode 编码
        num = num ^ i;#位异或
        num = num - ((i % 10) + 2);
        result3 += String.fromCharCode(num)#将 Unicode 编码转为一个字符
    }
    return result3
}

function ertqwe() {
    
    
    var temp_name = "user";
    var temp = getCookie(temp_name);#截取cookie中user变量的内容
    temp = decodeURIComponent(temp);#将cookie url解码,重新赋值到temp变量中
    var mingwen = decode_create(temp);#传入decode_create,经过一次加密后重新赋值给mingwen变量,这里的执行过程我在下面解析时有讲解
    var ca = mingwen.split(';');#切割,以分号切割,赋值ca变量中
    var key = "";
    for (i = 0; i < ca.length; i++) {
    
    
        if (-1 < ca[i].indexOf("flag")) {
    
    
            key = ca[i + 1].split(":")[2]
        }
    }
    key = key.replace('"', "").replace('"', "");
    document.write('<img id="attack-1" src="image/1-1.jpg">');
    setTimeout(function () {
    
    
        document.getElementById("attack-1").src = "image/1-2.jpg"
    }, 1000);
    setTimeout(function () {
    
    
        document.getElementById("attack-1").src = "image/1-3.jpg"
    }, 2000);
    setTimeout(function () {
    
    
        document.getElementById("attack-1").src = "image/1-4.jpg"
    }, 3000);
    setTimeout(function () {
    
    
        document.getElementById("attack-1").src = "image/6.png"
    }, 4000);
    setTimeout(function () {
    
    
        alert("你使用如来神掌打败了蒙老魔,但不知道是真身还是假身,提交试一下吧!flag{" + md5(key) + "}")
    }, 5000)
}

ertqwe() In the function, the content obtained by the mingwen variable

#原代码
var mingwen = decode_create(temp);

The above analysis of temp is our own cookie, I bring my own cookie into the decode_create() function to execute, and get the following

O:5:\"human\":10:{
    
    s:8:\"xueliang\";i:758;s:5:\"neili\";i:758;s:5:\"lidao\";i:61;s:6:\"dingli\";i:60;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\";}

Insert picture description here

Then I clicked on the earning function again

Insert picture description here
Bring the cookie into the script again to run and find the change.

Insert picture description here

The current idea is to change the cookie so that we can learn from the palm of the Buddha while making money

The way to change the cookie is to reverse-encode the plaintext:

At the beginning, I wrote reverse decryption for a long time, and found that when the encode in base64 was called, the original encryption code could not be solved, and the original cookie could not be encrypted by encode.

Insert picture description here
I guess there must be a problem with base64.js:

It is found that the encryption process does not correspond. Encode calls _utf8_encode
but decode does not call _utf8_encode

Insert picture description here
As long as we comment out the in encode, the input = _utf8_encode(input);plaintext can be de-encrypted. We copy base64 to the local for testing:

//1.html
<script>

function Base64() {
    
    
 
	// private property
	_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
 
	// public method for encoding
	this.encode = function (input) {
    
    
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
		//input = _utf8_encode(input); (注释掉这个函数调用)
		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;
	}
}


//原来我的cookie
var temp = "UTw7PCxqe3FjcC42OThOjWtSUFYwbm99amlzbG0wI3MeHBsUZ1liZxQMWEFDXl8EdUUOCgACd016B34WUlFWWTVoATEAAXF5P3Z2CmYgPTY5Pj90FSUUaGUfL2ZnYnYhCRMTGRQPQCcHKFIvEShXUlYCGQMbDQ4FXEcXREo/BTzBxKbu6fbrB+H+ps3nsLrP6dCs0LgR8fj1/+6y3+/apJ3XnJnkjNPf0NnRjpPD7pjzzfaMiJDcxt/XkP/B+I2C5vTqgUE=";
//进行加密,获取明文

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);
}
document.write("原明文:"+result3+'<br/>');
document.write('<br/>');
//修改明文
var result3 = 'O:5:"human":10:{s:8:"xueliang";i:830;s:5:"neili";i:602;s:5:"lidao";i:95;s:6:"dingli";i:63;s:7:"waigong";i:0;s:7:"neigong";i:0;s:7:"jingyan";i:0;s:6:"yelian";i:0;s:5:"money";i:200000;s:4:"flag";s:1:"0";}';

//反编码获取cookie
var result = "";
for (i = 0;i<result3.length;i++){
    
    
	num = result3[i].charCodeAt();
	num = num + ((i % 10) + 2);
	num = num ^ i;
	result += String.fromCharCode(num);
}
var temp= base.encode(result);

//将cookie进行url编码
temp = encodeURIComponent(temp);
document.write("cookie:"+temp+"</br>");
</script>

The de-encoded cookie will be output on the browser,

UTw7PCxqe3FjcC42OThOjWtSUFYwbm99amlzbG0wI3MeHBsUZ1liZxQMWEFDXl8EdUUOCgACd016B34WUlFWWTVoATEAAXF5P3Z2CmYgPTY5Pj90FSUUaGUfL2ZnYnYhCRMTGRQPQCcHKFIvEShXUlYCGQMbDQ4FXEcXREo%2FBTzBxKbu6fbrB%2BH%2Bps3nsLrP6dCs0LgR8fj1%2F%2B6y3%2B%2FapJ3XnJnkjNPf0NnRjpPD7paIiIiIhovBiIL4kNTK0dea%2F7mC%2B4bu%2FOr1SQ%3D%3D

Insert picture description here
Copy it directly into our cookie, you can see that we now have 20W silver tael, which is pretty good.

Insert picture description here

Then go to the store to buy the Tathagata Palm, and fight against the old demon.

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_41924764/article/details/109488408