免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3804 | 回复: 0
打印 上一主题 下一主题

[Linux] [原创]Linux系统下Multicraft 2.1.1破解全过程(非伪站破解) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2017-02-25 13:36 |只看该作者 |倒序浏览
大家好,本人Linux内核工程师一枚,最近由于想组装一台家用版服务器,用来开Minecraft私服用,所以闲来无聊就到各大论坛寻找开服经验,发现各种关于MC开服的帖子都是使用Multicraft后台管理工具,由于本人工作和平时都是使用Linux操作系统,所以直接忽略WINDOWS开服方法。
安装方法:
首先在http://www.paopaoche.net/gonglue/92668.html网站中找到了Multicraft控制面板的安装方法,其中无数禁止访问的大坑,最后终于安装成功了。
不免得内心非常激动,于是迫不及待的弄了一台服务器装上CentOS系统,然后将Multicraft面版工具安装到服务器当中(安装过程略)然后欣喜若狂地用浏览器访问Multicraft面版,开启愉快的开服之旅。当我新建第一个服务器是悲惨的事情发生了。
对你没看错,服务器的人数不能多于10人。。。
起初我以为是什么设置没配置对,于是百度搜了一堆结果都是说Free版的Multicraft只能开一个服务器,而且人数必须小于10。此时我才意识到Multicraft是收费的,然而我并没有交钱。。。。。
破解启航:
我相信并不是只有我一个人遇到这个限制问题,于是又是百度各种搜索破解方法,但是都是在Windows系统下进行破解的教程,有的竟然都制作成了安装包,但是版本都比较老旧,我找到最靠谱的破解方法莫过于http://www.52pojie.cn/thread-344181-1-1.html帖子提到的建立伪站,向multicraft服务返回serial码。但是当我阅读完之后发现两个问题。
一)2.1.1版本的multicraft并没有pyd文件,官方将python写的代码全部编译为elf文件,并且二进制文件中并不存在调试信息。
二).htaccess文件怎么写?
三)KEY码写在哪里?
四)修改hosts文件以后更新核心文件怎么办?
在几经周折之后,终于在安装脚本中找到了KEY的存放路径,
就是存放在/home/minecraft/multicraft/multicraft.key文件中。
随后我又在贴吧找到这位大神装B的帖子https://tieba.baidu.com/p/4416959459?red_tag=3119352631,在文章末尾说无法用逆向工程的方式破解,这点倒是非常负责任的,接下来我们就来研究一下逆向工程来破解掉Multicraft的验证部分。
环境准备:
首先提到逆向工程大家第一时间会想到ollydbg,没错od确实是一个破解程序的利器,但是我还是习惯用Linux系统,这里我们就使用Linux下的调试程序gdb来实现逆向破解。
首先查一下Multicraft是如何使用的,我们进入到/home/minecraft/multicraft/bin目录下,运行./multicraft -h
可以看见各个参数的意义,-n为在前台运行,-s为不启动任何服务。
我们来使用GDB调试一下multicraft进程看看能得到哪些信息:
从图中可以看出有几个关键信息:
1)当multicraft服务获取到KEY后显示动态license模式。
2)启动线程与数据库进行连接,等待请求到来(线程不会退出)
3)启动线程监听21端口即ftp端口,与25465端口,等待浏览器请求到来。
4)启动线程并且脱离主进程,随后打印Verification Failed。。。。
5)multicraft程序并没有调试的debug信息。
到此我们可以分析出Multicraft的基本架构模式,为最基本的多线程异步IO模式,其中线程13565使用异步IO模型,在用一线程中同时监听连个端口。
我们验证一下Linux下使用异步IO的方法有三种,select() poll() 和epoll(),这样我们可以直接在这三个函数入口处设置断点。
可以看到,multicraft使用的是poll模型,与猜想基本吻合,但是第二个线程监听三个描述符,这点与猜想有一些小的出入,为什么会出现这种情况呢?有可能只有一个线程在执行监听工作,另一个线程用来处理请求,当然这也是猜想,需要进一步验证。
由于程序使用多线程模型,所以肯定会调用系统函数pthread_create函数,我们在线程创建入口设置断点后,运行程序:
可以看到有三处创建线程的地点,在第三个线程创建后显示认证失败信息,这样我们只需要修改线程三的入口函数的实现就可以达到绕过验证的目的,似乎胜利就在眼前了,线程函数的入口地址会在调用pthread_create时当作参数传递进来。
那么我们step进入到pthread_create函数中查看
函数地址在此,此时心动不已,然后我们只要在这个地址设置断点,然后进一步查看这个线程是如何工作的,就可以绕过破解了,理想总是很丰满,于是我们在0x7ffff7d32570地址处,设置断点。
当我设置完断点之后,我的内心瞬间崩溃了,大家可以看到,这个函数地址竟然debug调试信息,然而前文已经说过multicraft程序中并没有调试信息,为什么会这样呢?真相只有一个,就是这个地址是动态库的函数入口地址,而这个动态库编译时并没有去掉调试信息,所以gdb调试工具才会在动态库的二进制文件中获得这个函数的文件与行号。
然后我们来看一看在创建线程的时候堆栈调用的顺序,我们发现大量的Py开头的函数,然后我们看一下multicraft目录,当前目录下存在一个libpython2.7.so.0.1文件,原来是python库内部的代码,于是我们到python官网下载对应版本的安装包,到环境中编译:
编译成功后,当前目录下会出现一个libpython2.7.so.0.1,将这个文件替换到multicraft目录下,这样再进入python库函数后就可以查看变量的信息。
由于目标程序使用的是python语言编写,我们首先了解一下python线程的使用方法,在python或其他面向对象的语言中线程操作都被封在放到对象当中,首先声明一个线程对象,继承线程对象模块,重写父对象的run函数。
在主进程中实例化线程对象,调用对象的start方法再新线程中执行对象中的run函数中的代码,感兴趣的朋友可以学习一下python中的线程操作(这里不在赘述)。
上述线程流程编译到下层python库中后,会分成两部分,当主进程实例化线程对象时,底层会调用pthread_create函数创建线程,然后调用pthread_wait等待执行线程信号,当主进程调用线程start方法时,对应底层调用pthread_signal发送线程信号,释放等待,然后线程开始执行run函数。
然后我们猜想一下这个线程中的run函数都做了些什么操作呢?
1)创建socket连接,发送http请求数据。
2)接收服务器返回结果。
3)计算返回值合法性,输出debug信息
4)验证版本,输出info信息。
所以计算返回数据的逻辑应该位于接收返回数据之后与输出信息之前,这样就可以锁定我们攻击的目标范围,于是我们继续设置断点调试,首先在接收数据的函数sock_recv函数处设置断点并查看堆栈信息:
然后定位file_write,并且查看堆栈信息:
根据两个堆栈信息进行判断,核心计算的函数入口地址应该位于0xd79f90至0xb82ae4之间。
于是我们在0xd79f90处设置断点:
由于这部分函数编译之后并没有代码,所以我们使用gdb的x/i $pc命令来查看汇编代码,或者使用命令objdump -S multicraft>multicraft.s将二进制文件反汇编为汇编代码,由于静态反汇编只会转义代码段,所以在multicraft.s中并看不见其中的全局变量和字符串,话不多说我们继续往下按指令执行,当执行到0xd79ff6地址出突然返回到0xd78c43处,说明此处有循环。
我们找一下0xd78c43处的代码如下:
在地址0xd78c48处为调用函数,但是返回值使用-1判断是否正确,可以证明调用的并不是python的业务代码,经常编写面向对象语言通常会使用true与false两个变量来判断函数返回是否正确,即1和0,所以这个调用可能是python对象封装与系统调用之间的过渡函数,我们可以尝试一下修改寄存器的值,并且查看输出。
果然,程序中的run函数中的read函数出现异常,返回-1,随后校验线程退出,程序可以正常运行了,其实到这里逆向工程破解就已经接近尾声了。
最后需要校验这个函数地址是否为复用的函数地址,如果为复用的函数地址需要到上层函数中去修改返回值。验证复用函数就是将这个函数地址设置断点,然后启动程序,看这个断点是否只停止一次,如果停止多次,证明很多函数调用这个地址,需要查看堆栈信息去到上一层函数修改。
可能有的朋友还会问,这样能有什么用呢?总不能我每次开服都从gdb进入程序,然后设置断点,并且修改寄存器的值吧。
答案当然不会,接下来我们就开始修改程序将算法写到程序中,首先第一步就是寻找特征码,会做外挂或者从事安全工作的朋友可能非常了解,程序的特征码就是一段操作的机器编码,这里我们使用函数地址0xd78c48处的机器码作为特征码:
查找到特征码之后我们利用特征码查找函数地址在二进制文件中的位置,使用命令
hexdump -C multicraft |grep ‘xx xx xx xx xx’如图:
然后使用vim工具修改二进制文件,vim使用(略),首先vim -b multicraft打开文件,发现一堆乱码…….
输入命令:%!xxd
将ff改为真正的eax返回值1,则即使函数返回为True,python也一样会抛出异常,修改后输入命令:%!xxd -r从新保存为二进制文件。
然后我们再次运行multicraft查看输出信息:
输出与之前在GDB中一样,都是校验线程返回异常,这个结果其实已经可以正常使用multicraft面板进行开服了,并且不用出现任何限制,但是毕竟存在异常,作为有强迫症的我几经周折终于找到了校验Serial码的函数,成功绕过,感兴趣的朋友可以进一步寻找,我就不再赘述,下图为完美破解。

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP