这个游戏已经好久没有维护了,就连我也差点忘记自己还制作过这个游戏。不过没想到的是一直还有玩家在尝试过关,虽然和刚发布时候相比已经冷清很多。考虑到今后自己可能没有时间再出后续版本,同时对很多人来说,这个游戏的第二版或许难度高了些。也有人写信给我怀疑第二版根本无法通过。因此,我花了点时间,自己作为一名闯关者,把这个游戏过了一遍。下面就是我本人的过关方法,这个攻略应该说是“官方”版本了,也就是我出题时希望挑战者采取的方法。
虽然是面向初学者的游戏,挑战2还是有一定深度和可玩性的。没尝试过的朋友不妨借助这篇文章自己体验下:-)
转载注意.保留下面信息:
背景
高手挑战是我在发布自己网站之后不久制作的一款网页闯关游戏,原本只是为了好玩随便制作了下,但出乎我意料的是他的第一版在网络上大受欢迎。
接着我制作了这个游戏的第二个版本,他的难度和前一版相比有很大的提升,不再是简单的设计一些基础的操作能力。而是涉及互联网相关技术(HTTP协议/HTML/CSS/XML/RPC/FLASH/JavaScript等)、图像处理、音频处理、基本的反汇编调试技术、基本的网络安全技术、原始数据恢复等方面。同时游戏有不单单简单的考察这些知识,而是通过巧妙组织具有很强的趣味性。
游戏的URL是:http://www.csksoft.net/netcompet2/
与2005年年初发布,目前累计有50多人通过挑战,参与者9240人,通过率 <= 0.5%
通过上面数据,可以看出游戏还是具有一定的难度的。为了防止通过者将答案散步在网上,我对游戏也作了一定的处理,比如最终闯关成功认证时候需要验证码,而验证码是由之前闯关时游戏者收集到的验证码碎片通过特定的计算公式得出的。而验证码碎片以及计算公式对于不同玩家是不相同的。另外,游戏系统会纪录每个游戏者的游戏进度,一方面可以帮助游戏者下次登陆后能自动进入上一次的关卡继续游戏,同时也能在一定程度上防止提前进入没有通过的关卡(防止直接从网上看到答案)。
虽然这些手段不能非常有效地阻止答案泄露,但一定程度上还是有作用的。因此从游戏发布至今将近3年中,通过者寥寥无几,网上也很难找到比较完善的通关策略。
一共14关,每一关就是一个页面,游戏者需要做的就是通过当前关卡提供的信息,找到下一关的页面地址。
在通关过程中需要收集5个验证码片断
最终,通关者需要将收集来的验证码片断通过游戏提供的工具组合成最终的验证码,并通过最终的验证。此时闯关成功。
通关方法
下面介绍的方法是我自己亲自操作得来的,因此可以保证100%的正确性。
但是需要注意的是,就像上面提到的,具体的数据和方法对于每个人都存在差异,因此不可能照搬得来。
本游戏在中途关卡也做过调整,这次公布的方法包括了调整前后的差别。
第一关
地址:http://www.csksoft.net/netcompet2/gamearea/start2.htm
这一关的线索在网页源代码中,通过提示察看其中的CSS文件stdStyle.css
会发现如下代码:
URL:deefr3c.htm;
}
deefr3c.htm就是下一关地址
获得验证码碎片:CT02
第二关
地址:http://www.csksoft.net/netcompet2/gamearea/deefr3c.htm
这关是一个ASCII变换问题,由提示中给出的关系:@LE -> htm
通过查找ASCII码表可知,@与h,L与t,E与m他们的ASCII值均相差40,因此,可以只需要将本关给出的字符串:+L=J=G?J9E.@LE,一次把每个字符的ASCII值加40,遍可以获得下一关的地址。
上述计算可以手工查表计算,也可以编写程序获得。这里推荐利用我Flash网站的即时代码执行功能编程计算得到。下面是计算本关答案的ReformScript代码:
var src_text;
var dest_text;
src_text = "+L=J=G?J9E.@LE";
dest_text = "";
for (i=0;i<src_text.length;i++)
{
cur_ascii = src_text.charCodeAt(i);
if (src_text.substr(i,1) != ".") {
cur_ascii += 40;
}
dest_text+= String.fromCharCode(cur_ascii);
}
msgout(dest_text);
将上述代码复制入Flash网站并执行,获得结果:Stereogram.htm
第三关
地址:http://www.csksoft.net/netcompet2/gamearea/Stereogram.htm
按照提示的说明,下载页面上的图片文件:stere.jpg
下一关的信息就藏在该文件中,根据jpg的定义,其中允许保留创建程序的字段信息。可以通过16进制察看器观察。这里采用windows/DOS系统自带的debug工具。
在debug中输入如下指令:
L 100
D 100 L100
此时,该文件头部长度为0x100字节的数据显示如下:
-d100 L100
13D4:0100 FF D8 FF E0 00 10 4A 46-49 46 00 01 02 01 00 48 ......JFIF.....H
13D4:0110 00 48 00 00 FF E1 34 2C-45 78 69 66 00 00 4D 4D .H....4,Exif..MM
13D4:0120 00 2A 00 00 00 08 00 07-01 12 00 03 00 00 00 01 .*..............
13D4:0130 00 01 00 00 01 1A 00 05-00 00 00 01 00 00 00 62 ...............b
13D4:0140 01 1B 00 05 00 00 00 01-00 00 00 6A 01 28 00 03 ...........j.(..
13D4:0150 00 00 00 01 00 02 00 00-01 31 00 02 00 00 00 1B .........1......
13D4:0160 00 00 00 72 01 32 00 02-00 00 00 14 00 00 00 8D ...r.2..........
13D4:0170 87 69 00 04 00 00 00 01-00 00 00 A4 00 00 00 D0 .i..............
13D4:0180 00 00 00 48 00 00 00 01-00 00 00 48 00 00 00 01 ...H.......H....
13D4:0190 43 53 4B 53 4F 46 54 20-53 74 65 72 65 6F 69 63 CSKSOFT Stereoic
13D4:01A0 20 4B 65 79 3A 44 72 65-61 6D 69 6E 67 43 68 69 Key:DreamingChi
13D4:01B0 6C 64 2E 68 74 6D 20 42-65 20 43 61 72 65 00 00 ld.htm Be Care..
13D4:01C0 00 00 00 03 A0 01 00 03-00 00 00 01 00 01 00 00 ................
13D4:01D0 A0 02 00 04 00 00 00 01-00 00 02 42 A0 03 00 04 ...........B....
13D4:01E0 00 00 00 01 00 00 01 AE-00 00 00 00 00 00 00 06 ................
13D4:01F0 01 03 00 03 00 00 00 01-00 06 00 00 01 1A 00 05 ................
注意上述红字部分,得到字符串DreamingChild.htm
此时,大部分玩家会以为下一关的地址就是http://www.csksoft.net/netcompet2/gamearea/DreamingChild.htm
虽然上述链接的确会进入一个关卡,但显示为3.5关。这是一个陷阱,此时需要回到第三关页面,在html代码中找到注释的代码:
<!--
别忘了这里!
<TitleName>.<ExtName>
Asc(<NewName>(n))=Asc(<TitleName>(n))+1 'where n ranges from 1 to Length(<TitleName>)
FinalData:<NewName>.<ExtName>
-->
说明下一关的正确地址是需要通过对前面得出的字符串作一定变换得来的,阅读伪代码,很容易知道这也是一个ASCII变换问题。可以通过修改之前给出的ReformScript代码计算出本关答案:
var src_text;
var dest_text;
src_text = "DreamingChild";
dest_text = "";
for (i=0;i<src_text.length;i++)
{
cur_ascii = src_text.charCodeAt(i);
cur_ascii += 1;
dest_text+= String.fromCharCode(cur_ascii);
}
msgout(dest_text);
执行上述代码,得到结果:EsfbnjohDijme,因此,下一关地址为EsfbnjohDijme.htm
第四关
地址:http://www.csksoft.net/netcompet2/gamearea/EsfbnjohDijme.htm
这一关页面中,要求闯关者输入正确的密码以便进入下一关。
当然这不可能要求闯关者去猜测出密码,破解的思路是查看页面代码,会发现如下的JavaScript:
if (pass ==GetPassWord()) {
alert("密码正确");
location.href = GetNextStg();
}
else {
alert("密码错误!");
location.href = "http://www.csksoft.net";
}
}
很明显,这段代码是用于判断输入的密码是否正确,而程序仅仅是通过将输入的密码pass和由函数GetPassWord()给出的正确密码进行比较。因此,破解的思路就是设法获取GetPassWord()函数的返回值或者查看函数代码。
继续分析页面源代码,会发现GetPassWord函数是由GetPassWord.asp文件给出的:
尝试下载该文件,发现其中的内容是代码:
十分令人吃惊的代码,因此,所需要的密码就是Stereoic。在输入密码后,便自动进入了下一关。
第五关
地址:http://www.csksoft.net/netcompet2/gamearea/hardDays.htm
这关涉及Flash的逆向工程和破解。
页面上Flash逐渐显示着下一关的地址,然而显示到中途却停止了。无法看到下一关地址的后半部分。此时需要通过对swf文件进行逆向工程,分析并提取其中的素材来获得答案。
分析本关页面,当前现实的flash文件是mainStg.swf,将它下载至本地后,使用相关的逆向工程工具分析,这里采用SWFDecompiler。
分析其中第一祯的代码:
发现具有下一关地址信息的flash文件并不是mainStg.swf,而是另一个文件:nextlevel.swf。因此将nextlevel.swf下载到本地,利用SWFDecompiler提取其中的图片资源,下一关的地址便出现了:
第六关
地址:http://www.csksoft.net/netcompet2/gamearea/dejvsdewd.htm
这关没有任何技术难度,伪造了IE5.0的404默认显示页面。如果足够细心,就能发现。下一关地址使用白色字体存在于这个"404错误"的页面里,用ctrl+a反色显示就能发现
第七关
地址:http://www.csksoft.net/netcompet2/gamearea/eng-sfcd.htm
同样也是没有难度的关,页面中需要填完整的句子是
因为在这句话中,26个英文字母都出现了,所以常用于测试字体显示效果。在windows中的英文字体浏览就使用了这句话。
这关答案就是dog.htm
第八关
地址:http://www.csksoft.net/netcompet2/gamearea/dog.htm
这关只需要下载那段录音,使用相关音频处理工具,比如以前的cooledit,将播放速率降低即可。将听到的单词记下来,就是下一关地址
第九关
地址:http://www.csksoft.net/netcompet2/gamearea/goodday.html
这一关首先需要下载我编写的Stereoic程序,同时要借助一些调试工具。
通过如下命令行来执行StereoPower:
此时会弹出一个消息框,其中有与下一关相关的字符串:bmbouvsjohstbhbz
同时注意到页面中的文字:
CAESAR实际上就是上面获得的字符串,它实际也是一个ASCII变换处理,同样,利用上面的ReformScript做修改,就能获得下一关地址:
var src_text;
var dest_text;
src_text = "bmbouvsjohstbhbz";
dest_text = "";
for (i=0;i<src_text.length;i++)
{
cur_ascii = src_text.charCodeAt(i);
cur_ascii -= 1;
dest_text+= String.fromCharCode(cur_ascii);
}
msgout(dest_text);
获得的结果是:alanturingrsagay
所以答案就是alanturingrsagay.htm
同时,这一关还需要收集验证码碎片,但很多闯关者都会忽略。
获得验证码碎片的方法是需要修改Stereoic.exe的资源文件,可以用EXESCOPE或者Visual C++的资源编辑器修改。找到其中的图案设置对话框,会发现Visible=FALSE属性的按钮,将它设为可见,保存修改
运行程序,点击那个按钮,从弹出的提示中知道StereoPower.exe的一个调用格式:
StereoPower.exe -p [fileSrc] [fileDest]
不过这次是需要获得程序的进程返回值,可以用Ollydbg或者Visual C++作为调试器调用程序获得,或者自己编写程序。这里给出相关的C代码片断:
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
DWORD Exitcode;
ZeroMemory(&sinfo,sizeof(STARTUPINFO));
sinfo.cb=sizeof(sinfo);
sinfo.dwFlags=STARTF_USESHOWWINDOW;
sinfo.wShowWindow=SW_SHOW;
CreateProcess(NULL,"StereoPower.exe /?",NULL,NULL,FALSE,
NORMAL_PRIORITY_CLASS,NULL,NULL,&sinfo,&pinfo);
WaitForSingleObject(pinfo.hProcess, INFINITE);
GetExitCodeProcess(pinfo.hProcess,&Exitcode);
最终,程序的进程返回值会保存在变量Exitcode中,他就是本关的验证码碎片
第十关
新地址:http://www.csksoft.net/netcompet2/gamearea/alanturingrsagay.htm
废弃地址:http://nofrost.nease.net/alanturingrsagay.htm
关于这一关地址的变更以及废弃的关卡解法参考:http://www.csksoft.net/blog/post/48.html
这一关是常识问题,答案是ajax。
第十一关
地址:http://www.csksoft.net/netcompet2/gamearea/ajax.htm
这关涉及数据分析技巧,下载页面中的那个二进制数据后,首先用16进制编辑器打开,察看数据。这里仍旧采用debug程序
-N bin.dat
-L100
-d100 l100
13D4:0100 73 61 6D 70 6C 65 2E 62-6D 70 00 00 00 00 00 00 sample.bmp......
13D4:0110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
13D4:0120 00 00 30 30 30 30 30 30-31 30 30 30 40 30 30 30 ..0000001000@000
13D4:0130 31 36 31 31 37 31 30 00-00 00 00 00 00 00 00 00 1611710.........
13D4:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
13D4:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
13D4:0160 00 00 00 00 00 00 6D 61-69 6E 64 61 74 61 2E 6A ......maindata.j
13D4:0170 70 67 00 00 00 00 00 00-00 00 00 00 00 00 00 00 pg..............
13D4:0180 00 00 00 00 00 00 00 00-30 30 30 31 36 31 32 37 ........00016127
13D4:0190 34 36 40 30 30 30 30 30-36 32 34 31 31 00 00 00 46@0000062411...
13D4:01A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
13D4:01B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
13D4:01C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
13D4:01D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
13D4:01E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
13D4:01F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
该文件类似于一种打包文件格式。在文件头部给出了该文件中所包含的2个文件,他们的文件名就是上面的红字部分。
接下来的任务就是确定这2个文件在此打包文件中的位置和大小。分析上面的蓝字部分。
可以猜测出,@符号前面的数字为本文件在此打包文件中的起始位置(偏移量),@后面的数字自然就是文件长度。不过需要注意的是这里的数字都是8进制格式的,这一点比较难发现。
对上述数字作进制转化:
0000001000(Oct) -> 512(Dec) -> 0x200
0001611710(Oct) -> 463816(Dec) -> 0x713C8
0001612746(Oct) -> 464358(Dec) -> 0x715E6
0000062411(Oct) -> 25865(Dec) -> 0x6509
接下来把相关的数据单独提取保存就能得到sample.bmp和maindata.jpg这2个文件。
这里给出已经提取出来的版本:http://www.csksoft.net/data/netcompetII_solution/bin.rar
接下来分析sample.bmp。按照图片的提示,同时需要联系第一版本的高手挑战。猜测这个bmp中有隐藏数据。因此需要使用我网站上提供的picmixer工具,将隐写在bmp中的数据提取出来。picmixer的下载地址是:ftp://FTP_Visitor:visitor@ftp.csksoft.net/Public/Products/APP/picmixer.rar
或者在Flash网站中的作品区也能找到下载。
对bmp中隐写数据的提取,能得到文件SerialNum.txt。他的内容为:
打开另外一个文件maindata.jpg,里面就是下一关的地址
第十二关
地址:http://www.csksoft.net/netcompet2/gamearea/decoder.htm
这一关与之前要求输入密码类似,但察看源代码发现没有任何线索。
实际上他考察了对SQL注入漏洞的了解,用经典的注入代码:
作为用户名和密码,就能十分轻松的过关。
本关验证码碎片:jTv
第十三关
地址:http://www.csksoft.net/netcompet2/gamearea/package.htm
这一关实际上要求以下面的HTTP header来请求页面:http://www.csksoft.net/netcompet2/gamearea/package.asp
ReferenceURL: http://www.sjtu.edu.cn/index.htm
请求的页面会检查这2个字段,如果不满足一些必要的信息,就会拒绝显示内容。解决办法可以利用诸如FlashGet等下载工具中定义这2个字段的数据来访问网页实现。或者可以自己编写http客户端程序。
如果能成功获取请求页面的数据,下一关地址便可得到。
第十四关(最终关)
地址:http://www.csksoft.net/netcompet2/gamearea/ffeewwdd.htm
这一关主要涉及程序的调试和逆向工程技巧,主要任务是破解用于合成最终验证码的程序。
该程序需要输入用户名和序列号后才能使用,但是对于闯关者来说不可能知道自己的序列号是什么,因此需要通过相关的技巧,要么获取序列号,要么强行绕过程序的检验。
这里分别介绍这2种办法。
1.获取正确的序列号
当然有足够精力的话可以逆向工程来分析序列号算法,自己写注册机,但是对于本程序,只需要用最简单的内存搜索即可。
先随便输入用户名和序列号,比如:
然后在该程序进程内存中搜索随便输入的序列号,这里是cskcskcsk。采用的工具可以使Ollydbg或者WinHex,下面是WinHex的搜索结果:
会发现在cskcskcsk字符串下方的就是正确的注册码,因为本程序采用的是十分危险的明文校验,所以可以用这样简单的办法获取
此办法操作简单,有效,因此是推荐的做法。不过也可以直接通过修改跳转指令破解注册码验证来实现对程序功能的应用。
这里给出一种破解办法,具体思路省略。
使用Ollydbg分析程序,找到如下部分:
00402CDC . E8 F3980000 call 0040C5D400402CE1 . 83C4 08 add esp, 8
00402CE4 . 85C0 test eax, eax
00402CE6 . 8B4424 08 mov eax, dword ptr [esp+8]
00402CEA . 0F95C3 setne bl
00402CED . 83C0 F0 add eax, -10
00402CF0 . 8D48 0C lea ecx, dword ptr [eax+C]
00402CF3 . 83CA FF or edx, FFFFFFFF
00402CF6 . F0:0FC111 lock xadd dword ptr [ecx], edx
00402CFA . 4A dec edx
00402CFB . 85D2 test edx, edx
00402CFD 7F 08 jg short 00402D07
00402CFF . 8B08 mov ecx, dword ptr [eax]
00402D01 . 8B11 mov edx, dword ptr [ecx]
00402D03 . 50 push eax
00402D04 . FF52 04 call dword ptr [edx+4]
00402D07 > 84DB test bl, bl
00402D09 . 5B pop ebx
00402D0A . 6A 00 push 0
00402D0C 74 22 je short 00402D30
00402D0E . 6A 00 push 0
00402D10 . 68 547C4200 push 00427C54
上述部分为验证注册码是否正确的片段,在执行call指令前,就能发现堆栈顶部就是正确的注册码,因此可以通过对此处的拦截实现注册机。也可以修改第二处红色部分,即je跳转,将它修改为强制跳转jmp。就实现了绕过注册码检测的功能。
这里给出采用上述破解办法修改的程序:http://www.csksoft.net/data/netcompetII_solution/SerialChk_cracker.rar
最终,就出现了验证码合成的界面:
填入上面收集到的验证码碎片后,就能获取最终验证码。最后只需通过系统验证便宣告过关:
后记
终于写完了这篇“攻略”。说实话,在3年后我自己重新玩这个游戏也被困住了。很多东西我自己也生疏了,难道这几年来我在退步?不管如何,写完这篇文章代表这个游戏已经告一段落。看着那么长的攻略,觉得那些通关的朋友真的很不容易。毕竟要揣摩别人的心思比技术本身要难得多。
对于很多人而言,这个游戏还是有难度的。希望通过这篇文章,不但是介绍过关的思路,我更是希望能让更多人了解这些领域的相关知识和趣味。
最后说明的事如果对文章中有不理解的部分,请自行网上查找,本人不负责解答。如果有任何错误,希望能告诉我,我会立刻修正。