1.17 页游作弊和信息搜集

基于页游的前端分析

Google小恐龙

链接:T-Rex 在线版的chrome恐龙游戏

F12打开开发者模式,选择控制台Console,输入:

关闭GameOver判定:Runner.prototype.gameOver = function(){}

调整速度:Runner.instance_.setSpeed(1000);

2048

链接:2048

F12打开开发者模式,选择应用程序Application

在本地存储Local Storage中可以看到存储在本地的游戏数据,例如:

1
{"grid":{"size":4,"cells":[[null,null,null,{"position":{"x":0,"y":3},"value":2}],[null,null,null,null],[{"position":{"x":2,"y":0},"value":4},null,null,null],[null,null,null,null]]},"score":0,"over":false,"won":false,"keepPlaying":false}

通过修改即可改变棋盘中的数字。

数独

链接:数独游戏 – 信息安全教学示例(随机题目)

右键检查源代码可以发现网页生成题目并渲染的逻辑。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const { puzzle, solution } = generatePuzzle();

//创建一个style(css)放到网页里命名为secretStyle
const secretStyle = document.createElement('style');
//secretStyle的css里放题目答案,不予显示
secretStyle.textContent = `body::before{content:"${solution.join('')}";display:none}`;
//网页头部增加答案
document.head.appendChild(secretStyle);

//右键,查看源码看的是网页真实源码,不渲染

//elements里面是实时渲染的网页

最终在F12开发者模式的元素Elements中发现第二个<style>中有题目答案:

1
body::before{content:"789145263364729851215386479821593647576418932493672185957861324632954718148237596";display:none}

所以我们打开控制台执行:

1
2
3
4
5
6
7
8
9
//显示body::before的答案
const hidden = getComputedStyle(document.body,'::before').content.replace(/\"/g,'');
const digits = hidden.split('').map(Number);
console.log(digits);

//让答案显示在棋盘上
document.querySelectorAll('.cell').forEach((cell,i)=>{  
     if(!cell.disabled) cell.value = digits[i];  
   });

flappybird

链接:Floppy Bird

F12打开开发者模式,选择控制台Console,输入:

展示当前窗口的所有参数 console.log(window)

参考:

调整重力 gravity = 0.01

管道间距(依然有攻击判定) flyArea = 100

鸟跳的多高 jump = -4.6

管道真实高度 pipeheight = 200

修改best的分数 highscore = 999

玩家死亡 playerDead = function(){}

塔防

链接:HTML5 Tower Defense

右键检查源代码,发现游戏算法引入

1
<script type="text/javascript" src="td-pkg-zh-min.js?_t=1293962401.7"></script>

打开td-pkg-zh-min.js文件,发现设计师有提到cheat success!推测是设计师留下的秘籍。

进一步找到_TD.cheat="money+",推测出后面是要写内容的。

在控制台输入_TD.cheat="money+",发现金钱增加。

扫雷

链接:经典扫雷 (教学版)

右键检查源代码,发现整个棋盘为grid二维数组,二维数组内部嵌入字典,字典里面有isMine判断是不是地雷

因此在控制台使用输入下面的代码:

1
2
3
4
5
6
7
8
grid.forEach(row => {
    row.forEach(cell => {
        if (cell.isMine) {
            // 直接修改 DOM 样式
            cell.element.style.backgroundColor = 'red';
        }
    });
});

俄罗斯方块

链接:Tetris: Cyberpunk Edition

目标: 修改所有下落方块变为"L"形

右键检查源代码,发现生成下一个方块所用的随机函数:

1
2
3
4
5
6
7
8
9
createPiece: function(type) {
  if (type === 'I') return [[0, 1, 0, 0],[0, 1, 0, 0],[0, 1, 0, 0],[0, 1, 0, 0]];
  if (type === 'L') return [[0, 2, 0],[0, 2, 0],[0, 2, 2]];
  if (type === 'J') return [[0, 3, 0],[0, 3, 0],[3, 3, 0]];
  if (type === 'O') return [[4, 4],[4, 4]];
  if (type === 'Z') return [[5, 5, 0],[0, 5, 5],[0, 0, 0]];
  if (type === 'S') return [[0, 6, 6],[6, 6, 0],[0, 0, 0]];
  if (type === 'T') return [[0, 7, 0],[7, 7, 7],[0, 0, 0]];
},

因此需要修改上面的函数,去掉所有if,直接return"I"时的结果,

接下来console.log(window)查看网页参数,发现createPiece为Tetris的一个子参数,所以调用时要写全参数名为Tetris.createPiece

在控制台输入下面代码将参数修改,注意使用=将参数赋值:

1
2
3
Tetris.createPiece=function(type) {
	return [[0, 1, 0, 0],[0, 1, 0, 0],[0, 1, 0, 0],[0, 1, 0, 0]];
}

打砖块

链接:CYBER ARKANOID 3077

console.log(window)查看网页参数

思路一:Game.paddle.width = 800;修改挡板宽度

思路二: 每10ms获取一次球的x坐标,并设置挡板坐标中心始终对准小球

1
2
3
setInterval(()=>{
    Game.paddle.x = Game.ball.x - Game.paddle.width / 2;
},10)

贪吃蛇

链接:贪吃蛇 (自动加速版)

使用AI生成的外挂代码:

  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
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 1. 备份原函数
if (!SnakeGame.originalUpdate) {
    SnakeGame.originalUpdate = SnakeGame.update;
}

// --- 辅助函数:泛洪算法 (计算某一点周围有多少空地) ---
// 这是一个简化版 BFS (广度优先搜索)
SnakeGame.countFreeSpace = function(startX, startY, maxCheck) {
    let queue = [{x: startX, y: startY}];
    let visited = new Set();
    visited.add(startX + ',' + startY);
    let count = 0;

    // 为了性能,我们不需要计算整个地图,只要空间大于蛇的长度就认为安全
    while (queue.length > 0 && count < maxCheck) {
        let p = queue.shift();
        count++;

        let dirs = [{x:0, y:-1}, {x:0, y:1}, {x:-1, y:0}, {x:1, y:0}];
        for (let d of dirs) {
            let nx = p.x + d.x;
            let ny = p.y + d.y;
            let key = nx + ',' + ny;

            // 检查边界
            if (nx < 0 || nx >= this.tileCount || ny < 0 || ny >= this.tileCount) continue;
            
            // 检查是否撞到蛇身 (注意:这里要模拟蛇尾移动后的状态,简单起见直接用当前身体)
            let isBody = false;
            for(let bodyPart of this.snake) {
                if (bodyPart.x === nx && bodyPart.y === ny) {
                    isBody = true; 
                    break;
                }
            }
            
            if (!isBody && !visited.has(key)) {
                visited.add(key);
                queue.push({x: nx, y: ny});
            }
        }
    }
    return count;
};

// 2. 重写更新逻辑
SnakeGame.update = function() {
    let head = this.snake[0];
    let food = this.food;
    
    let moves = [
        {x: 0, y: -1}, {x: 0, y: 1}, {x: -1, y: 0}, {x: 1, y: 0}
    ];

    // --- 第一步:获取所有不立刻撞死的方向 ---
    let validMoves = moves.filter(move => {
        let nextPos = {x: head.x + move.x, y: head.y + move.y};
        // 撞墙/撞自己检测
        if (this.checkCollision(nextPos)) return false;
        // 反向掉头检测
        if (move.x === -this.velocity.x && move.y === -this.velocity.y) return false;
        return true;
    });

    // --- 第二步:给每个方向打分 ---
    // 评分标准:距离食物越近越好,但前提是空间必须足够
    let bestMove = null;
    let maxSpace = -1;
    let minDist = Infinity;

    // 如果没有可行方向,就只能等死了,保持原速
    if (validMoves.length > 0) {
        
        // 遍历所有可行方向
        validMoves.forEach(move => {
            let nextPos = {x: head.x + move.x, y: head.y + move.y};
            
            // 1. 计算该方向的“生存空间”
            // 我们只需要检测空间是否大于蛇的长度。如果空间 > 蛇长,说明进去后能转得开
            let space = this.countFreeSpace(nextPos.x, nextPos.y, this.snake.length + 5);
            
            // 2. 计算距离食物的距离
            let dist = Math.abs(nextPos.x - food.x) + Math.abs(nextPos.y - food.y);

            move.score = 0;
            move.space = space;
            move.dist = dist;
        });

        // --- 决策逻辑 ---
        
        // 策略 A: 优先找“空间充足”且“距离最近”的路
        // 过滤掉那些空间极其狭窄的死胡同 (空间 < 蛇身长度)
        let safeMoves = validMoves.filter(m => m.space > this.snake.length);

        if (safeMoves.length > 0) {
            // 如果有安全的路,选离食物最近的
            safeMoves.sort((a, b) => a.dist - b.dist);
            bestMove = safeMoves[0];
        } else {
            // 策略 B: 如果所有路都是死胡同(或者空间都不够),
            // 此时不要管食物了!选一个空间最大的方向苟延残喘,等待尾巴空出位置。
            validMoves.sort((a, b) => b.space - a.space);
            bestMove = validMoves[0];
        }
        
        this.velocity = bestMove;
    }

    // 执行原始逻辑
    this.originalUpdate();
};

查找真IP

CDN功能: 缓存和保护网站

因为cdn服务架构简单,所以几乎绝对防御,但是防不住ddos

如何绕过cdn?

http://cdn.chinaz.com/

https://ping.chinaz.com/

如果目标网站出现的ip都是不一样,说明使用了cdn

考虑使用冷门ip,因为这些第三世界国家可能没有cdn


dns查询

https://dnsdb.io/zh-cn/

微步在线

https://x.threatbook.cn/

dns和ip查询

http://viewdns.info/

tracert www.cctv.com

追踪去目标经历了多少跳,把数据包ttl调整为1,2,3,4.。。。。。直到目标位置,此时可以看到每个处理这个数据包的路由器ip地址是什么

中途会发现有的路由器不给你显示ip地址(骨干路由器,做了ip屏蔽不给外人显示ip)

ping人的时候TTL=64 TTL指time to live

使用邮件,pop3 smtp有概率可以看到cdn背后的目标

点击显示邮件原文绕过cloudflare

全网扫ip

https://github.com/superfish9/hackcdn

https://github.com/boy-hack/w8fuckcdn

host修改

确定目标本尊ip之后,需要修改自己电脑的host文件才能正确攻击

C:\Windows\System32\drivers\etc\hosts

电脑解析ip地址优先解析hosts文件

网络空间搜索引擎

https://fofa.info/

body="发送验证码" && country="CN"

查找网页中包含“发送验证码”,且位于中国的网站

app="CCTV-Cameras"

查找监控摄像头,根据找到的目标特征,去搜索默认密码

port="80"

只搜索某个端口

region="Zhejiang" && host="gov.cn" && city="Hangzhou"

限定地区进行信息搜集

Licensed under CC BY-NC-SA 4.0
已存在于互联网
发表了126篇文章 · 总计210.25k字
萌ICP备20267077号
Powered by ctOS