江湖魔头

开卷看题

浓重的网游风

刷新几次都差不多,直接干

emmm…….从属性上看,想正常通关可能要1W年,怎么办呢?

作为一名DNF老玩家,深知装备不好的痛,所以解决之路…..肯定是开挂啊

外挂研发之路

第一步:找可修改的敏感资源

看来看去,只有COOKIE值很可疑,不过加密了

第二步:解密敏感资源

首先尝试直接URL解码->BASE64解码

不出所料,失败了,不过既然是CTF,加密函数多少都会有点提示,康康源码

第三步:源码审计

md5.js和base64.js应该是引用公开的源码,script.js看着就问题很大而且做了混淆,BUT这能难得住我吗

这个混淆的名字我忘了,但是怎么处理记得很清楚,把eval删除其余的直接扔进console

光速获取源码,分析一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.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 ertqwe() {
var temp_name = "user";
var temp = getCookie(temp_name);
temp = decodeURIComponent(temp);
var mingwen = decode_create(temp);
var ca = mingwen.split(';');
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函数之后可以获取flag,不过是MD5形式的,所以现在的任务就是找到原始key

虽然觉得不会这么容易,但是不管怎么样先试试,打开console执行ertqwe函数

whatfk????简直就是逗我,看来这题没这么简单,继续审计源码

看来想获取key还是要先打败魔头…..

第四步:篡改游戏数据

数组还是不够直观,反序列化一下

人物属性都在其中,只要修改数值重新加密发送打败魔头应该就能获取key了

大致流程:提取cookie–>解密–>修改数据–>加密–>发送至服务器–>对返回的数据再次解密–>提取key

解密搞定了,剩下的就是加密了,加密应该是解密的反操作,分析解密函数

1
2
3
4
5
6
7
8
9
10
11
12
function decode_create(temp) {
var base = new Base64(); // 创建Base64对象
var result = base.decode(temp); // 对temp变量b64解码
var result3 = "";
for (i = 0; i < result.length; i++) {
var num = result[i].charCodeAt(); // 把字符转换为Unicode编码
num = num ^ i; // Unicode编码和下标异或
num = num - ((i % 10) + 2); // 数值变换
result3 += String.fromCharCode(num) // 将Unicode编码转换为字符并追加至结果
}
return result3
}

根据解密函数写出加密函数

1
2
3
4
5
6
7
8
9
10
11
12
function encode_create(temp) {
var result3 = "";
for (i = 0; i < temp.length; i++) {
var num = temp.charCodeAt(i);
num = num + ((i % 10) + 2);
num = num ^ i;
result3 += String.fromCharCode(num);
}
var base = new Base64();
var result1 = base.encode(result3);
return result1;
}

此外,贴出辅助函数

1
2
3
4
5
6
7
8
function encrypt() {
var str = 'O:5:"human":10:{s:8:"xueliang";i:537;s:5:"neili";i:618;s:5:"lidao";i:59;s:6:"dingli";i:77;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";}';
var miwen = encode_create(str);
var encrypt = encodeURIComponent(miwen);

console.log(encrypt);
document.cookie = "user=" + encrypt;
}

我们缺的其实就是一个字:钱(本次修改为20W元宝)

在console中执行函数,修改客户端数据

点击属性查看是否修改成功

这……肯定是出问题了,重新翻看源码

编码解码不对称,果然有问题(不愧是我),注释掉编码中指定的行

在线修改源码很麻烦,所以个人把源码copy到本地修改后生成加密的cookie

修改数据后刷新一下看看效果

YES,摇身一变成土豪,接下来就是愉快的买买买了,最后一掌打死老恶魔

后记

通过花钱可以知道各个属性的最大值,那么。。。如果超出范围呢,比如都是经典的8个9

还是别太贪了