阻止人们入侵Flash游戏的基于PHP的高分表的最好方法是什么

时间:2020-03-05 18:56:24  来源:igfitidea点击:

我说的是一个动作游戏,没有最高分数限制,也没有办法通过重播动作等方法来验证服务器上的分数。

我真正需要的是Flash / PHP中最强大的加密功能,以及一种防止人们通过我的Flash文件以外的方式调用PHP页面的方法。过去,我尝试过一些简单的方法,可以对单个分数进行多次调用,并完成校验和/斐波那契序列等,还使用Amayeta SWF Encrypt对SWF进行模糊处理,但最终它们都被黑了。

感谢StackOverflow的响应,我现在可以从Adobe http://www.adobe.com/devnet/flashplayer/articles/secure_swf_apps_12.html和https://github.com/mikechambers/as3corelib找到更多信息,我认为我可以使用用于加密。不能确定这会让我绕过CheatEngine。

如果它们不同,我需要知道AS2和AS3的最佳解决方案。

主要问题似乎是TamperData和LiveHTTP标头之类的,但是我知道还有更先进的黑客工具,例如CheatEngine(感谢Mark Webster)

解决方案

回答

我们可能会问错问题。我们似乎专注于人们用来打高分列表的方法,但是到目前为止,阻止特定方法仍然有效。我没有使用TamperData的经验,所以我无法对此讲话。

我们应该问的问题是:"我如何验证提交的分数是有效和真实的?"具体实现方式取决于游戏。对于非常简单的益智游戏,我们可以将比分以及特定的开始状态和导致结束状态的移动顺序发送出去,然后使用相同的移动在服务器端重新运行游戏。确认指定的分数与计算出的分数相同,并且仅在匹配时接受分数。

回答

使用已知的(私有)可逆密钥加密将是最简单的方法。我还没有完全了解AS,所以不确定是否有哪种加密提供程序。

但是我们可以包含一些变量,例如游戏时长(再次加密)和点击计数。

诸如此类的所有事情都可以进行逆向工程,因此请考虑放入大量垃圾数据以使人们摆脱这种气味。

编辑:也许值得在某些PHP会话中使用。当他们单击开始游戏并(如该帖子的评论所述)记录时间时,开始会话。当他们提交分数时,我们可以检查他们是否真的有一个开放游戏,并且他们提交的分数没有太快或者太大。

也许应该计算出一个标量,看看每秒钟/分钟的最高得分是多少。

这些事情都不是不可回避的,但是在人们可以看到的Flash中没有某些逻辑会有所帮助。

回答

每当高分系统基于Flash应用程序通过网络发送未经加密/未签名的高分数据的事实时,就可以对其进行拦截和处理/重放。答案是:加密(体面!)或者用密码签名高分数据。至少,这使人们更难破解高分系统,因为他们需要从SWF文件中提取密钥。许多人可能会在那里放弃。另一方面,只需要一个人就可以提取密钥并将其发布到某个地方。

真正的解决方案涉及Flash应用程序与highscore数据库之间的更多通信,以便后者可以验证给定的分数在一定程度上是现实的。根据我们拥有的游戏类型,这可能很复杂。

回答

因为它很容易反编译SWF,所以没有办法使其完全不可破解,然后,熟练的开发人员黑客可以跟踪代码,并弄清楚如何绕过我们可能采用的任何加密系统。

但是,如果我们只是想通过使用简单的工具(例如TamperData)来阻止孩子作弊,则可以生成一个加密密钥,然后在启动时将其传递给SWF。然后使用类似http://code.google.com/p/as3crypto/的方法对高分进行加密,然后再将其传递回PHP代码。然后在服务器端将其解密,然后再将其存储在数据库中。

回答

真正不可能实现我们想要的。 Flash应用程序的内部总是可以部分访问的,尤其是当我们知道如何使用CheatEngine之类的内容时,这意味着无论网站和浏览器服务器通信的安全性如何,克服它都将相对容易。

回答

一种简单的方法是提供高分值的加密哈希值以及它自己的分数。例如,通过HTTP GET发布结果时:
http://example.com/highscores.php?score=500&checksum=0a16df3dc0301a36a34f9065c3ff8095

计算此校验和时,应使用共享机密。这个秘密绝不应该通过网络传输,而应该在PHP后端和Flash前端中进行硬编码。上面的校验和是通过在字符串" secret"前面加上分数" 500"并通过md5sum运行它来创建的。

尽管此系统将阻止用户发布任意分数,但是它不能阻止"重播攻击",即用户重新发布先前计算的分数和哈希组合。在上面的示例中,分数500始终会产生相同的哈希字符串。通过在要散列的字符串中包含更多信息(例如用户名,时间戳或者IP地址),可以减轻某些风险。尽管这不会阻止数据的重放,但可以确保一组数据仅一次对单个用户有效。

为了防止发生任何重播攻击,必须创建某种类型的质询-响应系统,例如:

  • Flash游戏("客户端")执行不带参数的HTTP GET http://example.com/highscores.php。该页面返回两个值:一个随机生成的盐值,以及与共享机密结合的该盐值的加密哈希。此盐值应存储在待处理查询的本地数据库中,并应具有与其相关的时间戳记,以便它可能在一分钟后"过期"。
  • Flash游戏将盐值与共享机密结合在一起,并计算哈希值以验证它与服务器提供的哈希值匹配。此步骤对于防止用户篡改盐值是必要的,因为它会验证盐值实际上是由服务器生成的。
  • Flash游戏将盐值与共享的机密,高分值和任何其他相关信息(昵称,ip,时间戳)结合在一起,并计算哈希值。然后,它通过HTTP GET或者POST将该信息以及salt值,高分和其他信息发送回PHP后端。
  • 服务器以与客户端相同的方式组合接收到的信息,并计算散列以验证该散列是否与客户端提供的散列相匹配。然后,它还将验证盐值仍然有效,如挂起的查询列表中所列。如果这两个条件都成立,则将高分写入高分表,并向客户端返回签名的"成功"消息。它还从挂起的查询列表中删除盐值。

请记住,如果用户可以访问共享机密,则上述任何一种技术的安全性都会受到损害。

作为替代方案,可以通过强制客户端通过HTTPS与服务器进行通信,并确保将客户端预先配置为仅信任由特定证书颁发机构签名的证书,而我们自己可以访问这些证书,来回避免某些情况。

回答

我们正在谈论所谓的"客户端信任"问题。因为客户端(用现金,即在浏览器中运行的SWF)正在做它打算做的事情。保存高分。

问题是我们要确保"保存得分"请求来自Flash电影,而不是某些任意的HTTP请求。一种可能的解决方案是在请求时(使用flasm)将服务器生成的令牌编码到SWF中,该令牌必须随请求一起保存才能获得高分。服务器保存该分数后,令牌将过期,不能再用于请求。

这样做的缺点是,每次加载Flash电影时,用户只能提交一个高分,而我们必须强迫他们刷新/重新加载SWF,然后他们才能再次播放新得分。

回答

这是互联网游戏和竞赛的经典问题。Flash代码可与用户一起确定游戏得分。但是用户不受信任,并且Flash代码在用户的计算机上运行。你是SOL。我们无法采取任何措施来阻止攻击者伪造高分:

  • Flash甚至比我们想象的要容易进行逆向工程,因为字节码已被很好地记录并描述了高级语言(动作脚本)---在发布Flash游戏时,无论我们是否在发布源代码,知道与否。
  • 攻击者控制Flash解释器的运行时内存,以便知道如何使用可编程调试器的任何人都可以随时更改任何变量(包括当前得分),或者更改程序本身。

对我们系统的最简单的攻击是通过代理运行游戏的HTTP流量,捕获高分保存并以更高的分数重播。

我们可以通过将每个高分存储区绑定到游戏的单个实例来尝试阻止此攻击,例如,在游戏启动时通过将加密令牌发送给客户端,如下所示:

hex-encoding( AES(secret-key-stored-only-on-server, timestamp, user-id, random-number))

(我们也可以使用会话cookie来达到相同的效果)。

游戏代码以高分保存将该令牌回显到服务器。但是,攻击者仍然可以再次启动游戏,获取令牌,然后立即将该令牌粘贴到重播的高分保存中。

因此,接下来,我们不仅要馈送令牌或者会话cookie,还要馈送高分数加密的会话密钥。这将是一个128位AES密钥,它本身已使用硬编码到Flash游戏中的密钥进行了加密:

hex-encoding( AES(key-hardcoded-in-flash-game, random-128-bit-key))

现在,在游戏发布高分之前,它会解密高分加密会话密钥,这是因为我们已将高分加密会话密钥解密密钥硬编码到Flash二进制文件中。我们可以使用此解密密钥以及高分的SHA1哈希来加密高分:

hex-encoding( AES(random-128-bit-key-from-above, high-score, SHA1(high-score)))

服务器上的PHP代码检查令牌以确保请求来自有效的游戏实例,然后解密加密的高分,检查以确保高分与高分的SHA1匹配(如果跳过此步骤) ,解密只会产生随机的,可能很高的分数)。

因此,现在,攻击者反编译Flash代码,并迅速找到AES代码,该代码像拇指酸痛地伸出来,尽管即使没有找到,也可以在15分钟内通过内存搜索和跟踪器对其进行跟踪("我知道我在这款游戏中的得分是666,所以让我们在内存中找到666,然后进行任何涉及该值的操作-哦,高分加密代码!")。有了会话密钥,攻击者甚至不必运行Flash代码。她获取了游戏启动令牌和会话密钥,并可以发回任意高分。

现在,大多数开发人员都放弃了–通过以下方式放弃或者破坏攻击者几个月:

  • 使用XOR操作加扰AES密钥
  • 用计算密钥的函数替换密钥字节数组
  • 在整个二进制文件中散布伪造的密钥加密和高分发布。

这全都是浪费时间。不用说,SSL也不会。当两个SSL端点之一为恶意时,SSL无法保护我们。

以下是一些可以真正减少高分欺诈的事情:

  • 需要登录才能玩游戏,让登录产生会话cookie,并且不允许在同一会话上多次启动游戏,也不允许同一用户进行多个并发会话。
  • 拒绝持续时间少于有史以来最短的真实游戏的游戏会话的高分(对于更复杂的方法,对于持续时间少于平均游戏时间2个标准偏差的游戏会话,尝试"隔离"高分)。确保我们正在服务器端跟踪游戏时长。
  • 从仅玩过一次或者两次游戏的登录中拒绝或者隔离高分,因此攻击者必须为创建的每个登录产生合理外观的"纸迹"。
  • 在游戏过程中," Heartbeat"得分很高,因此服务器可以在一个游戏的生命周期中看到得分的增长。拒绝不遵循合理分数曲线的高分(例如,从0跳到999999)。
  • 游戏过程中的"快照"游戏状态(例如,弹药量,关卡中的位置等),我们以后可以将其与记录的临时得分进行核对。我们甚至不必以某种方式来检测此数据中的异常。我们只需要收集它,然后可以回头再分析一下是否看起来很腥。
  • 禁用任何未通过安全检查的用户的帐户(例如,通过提交未通过验证的加密高分)。

请记住,虽然我们只是在阻止高分欺诈。我们无法采取任何措施来防止这种情况的发生。如果游戏中有钱,那么有人将击败我们想出的任何系统。目的不是阻止这种攻击;而是为了阻止这种攻击。这是使攻击变得更加昂贵,而不仅仅是真正擅长于游戏并击败它。

回答

我喜欢tpqf所说的话,但不是在发现作弊时禁用帐户,而是实施蜜罐,这样,每当他们登录时,他们就可以看到自己的黑名单,并且从不怀疑自己被标记为巨魔。 Google for" phpBB MOD Troll",我们将看到一个巧妙的方法。

回答

我通常在游戏会话的"幽灵数据"中包含高分条目。因此,如果我要制作赛车游戏,则会包含重播数据。我们通常已经具有用于重播功能或者重影竞速功能的重播数据(在上一场比赛中对战,或者在排行榜上与14号花花公子的对战)。

检查这些是非常费力的工作,但是如果目标是验证比赛中排名前10位的参赛作品是否合法,这可能是对其他人已经指出的安全措施的有用补充。

如果目标是使高分榜在线保持到最后,而无需任何人查看,这不会给我们带来多少。

回答

以我的经验,这最好是作为社会工程问题而不是编程问题来解决。与其着重于使自己不可能作弊,不如着眼于通过消除作弊的动机使其变得无聊。例如,如果主要诱因是公开可见的高分,则仅需延迟显示高分的时间,即可通过消除作弊者的积极反馈回路来显着减少作弊。

回答

新流行的街机游戏mod的执行方式是将数据从闪存发送到php,然后再发送到闪存(或者重新加载),然后再发送到php。这使我们可以做任何我们想比较数据的事情,也可以绕过发布数据/解密黑客之类的事情。一种方法是通过从php中向Flash分配2个随机值(即使运行实时Flash数据采集器也无法捕获或者看到),使用数学公式将分数与随机值相加然后使用用相同的公式将其反转,以查看分数最终与php匹配时是否与之匹配。这些随机值是永远不会可见的,它还会计时交易发生的时间,如果它超过几秒钟,那么它还会将其标记为作弊,因为它假定我们已停止发送以尝试找出随机值或者运行通过某种类型的密码计算数字,以返回可能的随机值以与得分值进行比较。

如果我们问我,这似乎是一个很好的解决方案,有人使用此方法是否会遇到任何问题?还是可能的解决方法?