|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 戴宇轩 于 2015-2-27 13:34 编辑
<过关攻略>
首先AT小甲鱼老师和版主们: @小甲鱼 @~风介~ @wei_Y (不分优先级, 仅根据UID大小排序)
Python 鱼C闯关攻略(这里都用的是Python 3), 程序都测试过, 运行正常:
第一关(welcome.html)
这一关有点弱智(¬_¬)...不能按右键, 那就按下F12调出开发者工具, 查看网页源代码, 注释里有一段写着: gogogo.html
So, 下一关地址是: gogogo.html
或者直接上Python!import urllib.request
print(urllib.request.urlopen('http://python.fishc.com/challenge/welcome.html').read().decode('utf-8'))
第二关(gogogo.html)
不要告诉我你没有发现过关地址:sweat:。。。
点击图片右上角, 直接进入下一关, Done!
第三关(hidden.html)
这一关跟第一关差不多, 不过这次直接右键, 查看源代码, 注释又很明确的写着: forward.html, 所以...
第四关(forward.html)
这一关的提示纯属迷惑人, 版主你这是玩我们?。。。
点击 Tip 按钮, 密码就在下面, 输入密码, 过关!
或者来个Pythonic一点的, 直接上脚本!import urllib.request
import re
data = urllib.request.urlopen('http://python.fishc.com/challenge/forward.html').read().decode('utf-8')
print(re.findall(r'[a-z]+\.html', data))
得到 randint.html, 输入地址, 过关!
第五关(randint.html)
这一关更简单了, Python下标从0开始, 0, 英文就是zero, 所以下一关地址...zero.html
第六关(zero.html)
网页标题写着: this is first, 显然过关地址是this.html,
什么? 问我为什么? 版主以前写的标题是: This is the answer, 翻译过来是: this是答案, 现在版主为了加大难度, 改了一下, 强烈建议大家揍版主
正确解法:
因为Python的禅(The zen of Python)写在this模块里, 所以答案是thisimport this
print(this.s)
第七关(this.html)
右边写着大大的2和2的上标, 是问2的多少次方
再看内容, 这关告诉我们一月有30天, 所以答案是2 ** 30?
那你就错了! 那是版主迷惑我们, 因为1月有31天, 所以结果是: 2 ** 31
脚本:print(str(2 ** 31) + '.html')
下一关地址是: 2147483648.html
第八关(2147483648.html)
这关让我们'解密', 看图片, 每个字母向后移动了三位, 我们再来看密码:
bhv,brx ilqg d sdvvzdug,lw'v 'loyni',exw li brx qhhg fudfn.
这里面有一个词用引号括了起来, 我们重点来看 'loyni' 这个词, 我们要写一个程序来将这个词的字母向后移动1~25位, 来看看有没有真正的'单词'。。。
过程就像: 第一次把a变成b, 第二次变成c......最后一次变成z
for i in range(1, 26): # 向后移1~25位
result = '' # 结果存放处
for j in 'loyni':
result += chr(97 + (ord(j) - 97 + i) % 26) # 考虑到超过z要回到a, 将结果加入result
print(result, i)
执行这个程序, 在执行到第20个循环时, 我们终于看到了一个真正的单词: 'fishc' !!!
那么下一关地址: fishc.html
过关!
第九关(fishc.html)
我们来看看网页源代码, 看到一大串密文, 把它复制下来, 并保存为 code.txt:f = open('code.txt')
temp = f.read()
f.close
接下来都要用到temp, 就是把下面的脚本接到上面的脚本上:result = '' # 这里放结果
for i in temp: # 逐个查看字符串
if i.isalpha(): # 如果i是字母
result += i # 将i放入结果
print(result)
或者你可以用正则
import re
print(''.join(re.findall(r'\w', temp)))
得到结果: carpediem
不过这样实在是大材小用!
再来一个很Pythonic的写法!print(''.join(i for i in temp if i.isalpha())) # 一行解决!
同样得到结果: carpediem
下一关地址: carpediem.html
第十关(carpediem.html)
这关要我们输入密码。。。
先看源代码, 有一行是这样的:if (passwd=="letgo") {alert("OK,密码正确!"); window.location="letgo.html";}
正常人应该都能看得懂一些的...翻译如下:
如果密码为letgo, 显示密码正确, 并进入letgo.html
So......输入密码letgo或者输入地址letgo.html
轻松过关!
第十一关(letgo.html)
这一关提示, 让我们点击密码页, 结果进入了论坛, 不要怀疑自己点错了。。。
仔细观察一下主页, 你会发现页面上方有一大串16进制的数字, 应该是ASCII码
我们些一段程序来将这些数字转为明文:source = '5A 75 6C 77 68 23 77 6B 68 23 66 72 67 68 31 4A 6F 68 75 6E 6C 27 61 6F 6C 27 64 76 79 73 6B 35'
source = source.split(' ') # 按照空格分离
result = ''.join(chr(int(i, 16)) for i in source) # 把16进制的ASCII码转为ASCII字符串, 因为是16进制, 所以要加上: 16
print(result)
Zulwh#wkh#frgh1Johunl'aol'dvysk5
结果, 我们得到了一堆没用的文字?
当然不是! 前面第八关不是用了字母后移的方法得到了明文吗?
我们试试用之前的程序来解密
首先把各种符号数字变成空格或者去掉
print("Zulwh#wkh#frgh1Johunl'aol'dvysk5".replace('#', ' ').replace("'", ' ').replace('1', ' ')[:-1])
得到结果Zulwh wkh frgh Johunl aol dvysk
等等! 我好像发现了什么!
密码中有两个大写字母, 很可能要将密码分成两部分!
将它们手动转换成这样(元组里两个字符串):
('zulwh wkh frgh', 'johunl aol dvysk')
我们再回到密码页, 发现密码的左右两边有一些点和杠
这难道是摩尔斯电码!?
翻译一下:
左边 ...-- 是 3
右边 --... 是 7
可能是要将字母向前或者向后移动3位和7位, 而我们有两个词组(刚才的元组)
那我们试试前面部分向后移动3位或23位(向后移动23位就是向前移动3位)
后面部分向后移动7位或者19位(向后移动19位就是向前移动7位)
我们写个程序来验证一下:
counter = True
for i in ('zulwh wkh frgh', 'johunl aol dvysk'):
result = []
if counter:
result.append('')
for j in i: # 后移3位
if j != ' ':
result[-1] += chr(97 + (ord(j) - 97 + 3) % 26)
else:
result[-1] += ' '
result.append('')
for j in i: # 前移3位
if j != ' ':
result[-1] += chr(97 + (ord(j) - 97 + 23) % 26)
else:
result[-1] += ' '
else:
result.append('')
for j in i: # 后移7位
if j != ' ':
result[-1] += chr(97 + (ord(j) - 97 + 7) % 26)
else:
result[-1] += ' '
result.append('')
for j in i: # 前移7位
if j != ' ':
result[-1] += chr(97 + (ord(j) - 97 + 19) % 26)
else:
result[-1] += ' '
print(result)
counter = False
得到结果:
第一个词组:
+3: cxozk znk iujk (wrong)
-3: write the code (right)
第二个词组:
+7: qvobus hvs kcfzr (wrong)
-7: change the world (right)
把对的部分拼到一起, 变成了:
write the code change the world
(让代码改变世界)
题目让我们找到回文字符串, 只有首字母是回文
取首字母, 得到wtcctw
所以我们得到了下一关地址(不是下关地址!): wtcctw.html
(−_−#)NiMa过这关真不容易!
第十二关(wtcctw.html)
这关看似让我们输入密码, 其实源代码里根本就没有下一关地址!
所以我们忽略密码
接下来看看剩下的部分:
True是唯一的单词
所以我们立刻得知下一关地址: true.html
第十三关(true.html)
这题似乎没有着手点。但是看看图片, 上面写了'zip', 所以网页名和zip有关
我们将网页名改成true.zip并下载
打开后竟然提示要密码!
没关系~~下载一个破解软件(破解zip密码的)
得到密码: ~@_#%$
输入密码并解压, 里面有一个txt文件, 打开它, 问我们有没有吃过'泡菜', 泡菜, 英文名pickle...
所以下一关地址就是: pickle.html
第十四关(pickle.html)
由于小甲鱼教我们pickle模块时, 习惯将pickle文件名写成*.pkl
根据题意, 结合13关方法, 下载pickle.pkl
所以我们用python的pickle模块打开它, 代码如下:import pickle
f = open('pickle.pkl', 'rb')
result = pickle.load(f)
f.close()
print(type(result), result)
我们发现得到的数据是一个列表, 里面存着几个字符串, 我们试着逐行打印它:password:
**** ****
****** ******
****** ******
****** ******
***** *****
**********
********
******
****
**
得到一个心形, 英文是heart
So, 下一关地址: heart.html
第十五关(heart.html)
这关的意思是让我们找出所有左右两边分别只有3个大写字母的小写字母
再来看看源代码, 里面有一串密码
提示写着: 这题可以用正则解, 所以我们用正则...我们将密码存在 code.txt 里:import re
f = open('code.txt')
string = f.read()
f.close
pattern = re.compile('(?<=[a-z][A-Z]{3})[a-z](?=[A-Z]{3}[a-z])') # 这是正则表达式, {3}表示重复三次, 应该能看懂吧...
result = re.findall(pattern, 'a' + string + 'a') # 为了匹配开头结尾, 在开头和结尾分别加上一个小写字母
print(''.join(result))
完成! 结果是onwya, 但是你会发现它不对, 因为它被打乱了!
所以我们再写这样一段, 来找出所有排列组合
import itertools
string = 'onwya'
urls = ('http://python.fishc.com/challenge/%s.html' % (''.join(i)) for i in itertools.permutations(string, 5))
itertools.permutations函数需要两个参数, 第一个是迭代对象, 第二个是从迭代对象里抽取几个不同的值(这里是5个)
现在urls里面存放着所有可能的网页名, 可以用来浏览, 网页格式是 http://python.fishc.com/challenge/某某某.html
于是我们找到了所有组合, 接着一个一个找?
那当然, 不过我们用urllib, 脚本如下:
import urllib.request
print('请稍等...')
for i in urls:
try:
urllib.request.urlopen(i) # 试着打开这个链接
except: # 如果报错(页面不存在)
continue # 尝试下一个地址
else: # 没有报错的话, 就是找到了过关地址
print('过关地址是:', i) # 将地址打印出来
break # 跳出循环
大功告成! 地址是noway.html
第十六关(noway.html)
这一关除了标题之外, 其他信息纯属迷惑人...
看看标题: Dawn!
那过关地址就是dawn.html。。。
(PS: 这是我除了第二关以外过的最快的一关(−_−#)。。。)
正确解法:
用记事本打开图片, 翻到最后, 写着下一关地址: dawn.html
第十七关(dawn.html)
这一关的提示似乎和下一关无关, 看看源代码, 里面有线索, 是一个由数字组成的地址, 进入下一个, 又有一条线索。。。据说有49层!
这样手真的会抽筋的。。。
不说了, 上脚本! 召唤(import)正则!import re
import urllib.request
pattern = re.compile(r'\d+\.html') # 过滤出线索提供的地址
url = 'http://python.fishc.com/challenge/%s' % (re.findall(pattern, urllib.request.urlopen('http://python.fishc.com/challenge/dawn.html').read().decode('utf-8'))[-1]) # 形成一个完整地址, 方便以后用
try:
while True: # 尝试每一个线索, 直到找不到线索为止
url = 'http://python.fishc.com/challenge/%s' % (re.findall(pattern, urllib.request.urlopen(url).read().decode('utf-8'))[-1]) # 替换为下一个地址
except: # 如果找完了所有线索
print(urllib.request.urlopen(url).read().decode('utf-8')) # 输出网页源代码
完成! 源代码里写着: 本关地址cramp.html
打开它, 提示写着: 本关地址 cramp.php
进入cramp.php
第十八关(cramp.php)
这关看似没有着手点, 实际上, 关键词是: 登录
我用的是firerox浏览器, 看到这个php有一个cookie, 里面有一个参数: login, 它的值为: no
cramp.php 提示我们要登录, 于是将login的值改成yes, 然后刷新
(如何改cookie? 网上教程多得是!)
教程: http://jingyan.baidu.com/m/article/6b18230954dbc0ba59e15960.html
接着, 网页上出现了下一关地址~: logins.html
请同时参考以下聊天记录~~~
wei_Y 2015-2-8 14:35
想让你们改cookies的。。
戴宇轩 2015-2-8 14:38
改cookies? 怎么改?
wei_Y 2015-2-8 14:40
把里面login的no改成yes。。
戴宇轩 2015-2-8 14:41
然后再打开网页?
wei_Y 2015-2-8 14:43
刷新。。
wei_Y 2015-2-8 14:44
靠。一不小心说出来了。。
第十九关(logins.html)
这一关的密码页提示我们要用IE5.79, 而网页用User-Agent来识别我们的浏览方式, 我们可以更改User-Agent, 改为 Mozilla/4.0 (compatible; MSIE 5.79; Windows NT 5.0), 脚本如下:import urllib.request
header = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.79; Windows NT 5.0)'}
data = urllib.request.urlopen(urllib.request.Request('http://python.fishc.com/challenge/logins.php', None, header))
print(data.read().decode('utf-8'))
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>loading.</title>
</head>
<body bgcolor="#E8F9E8">
<h1>Python——鱼C闯关。第十九关。</h1><hr>Yes,密码是fishcpython</body>
</html>
好的~~~我们有了密码, 接着回到logins.html, 输入密码
。。。。。。
不幸的是, 版主在源代码里多加了一个斜杠, 不能进入checks.php, 只能用程序代替了!import urllib.request
import urllib.parse
passwd = urllib.parse.urlencode({'passwd': 'fishcpython'}).encode('utf-8') # 密码
data = urllib.request.urlopen(urllib.request.Request('http://python.fishc.com/challenge/checks.php', passwd)) # 带密码进入checks.php
print(data.read().decode('utf-8')) # 查看源代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>loading.</title>
</head>
<body bgcolor="#E8F9E8">
<script>location.href='loading.html';</script></body>
</html>
所以下一关地址是 loading.html
第二十关(loading.html)
这一关还不是终点, 版主已经把密码告诉我们了。。。输入密码: woshikeaidexiaomima
然后在跳转的最后一瞬间看一下标签页!!!==。细心一点可以看到 先经过turn22.php, 再跳到 404.html, 来看一下turn22.html源代码:<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>404 NOT Found!</title>
</head>
<body>
<h1>Python——鱼C闯关。第21关。</h1>
<hr>
<div align="center">
<img src="pic/rsa/rsa.png">
<p>下关地址: ?????????.html</p>
</div>
<hr>
Tip: 简单粗暴就是干!<br />
公钥(2178551,2175599)<br />
密文[1704953, 968245, 778054, 778054, 1742841, 1573398, 1742841, 778054, 544638]
</body>
<!-- gift key: 1F8DD4B60ACFC294091D09954924C48E -->
<script>location.href='404.html'</script></html>
这就是传说中的RSA算法!?
上百度学习学习, 然后经过复杂的计算, 发现私钥等于公钥!
下面上一段程序来将密文解密:key = (2178551, 2175599) # 密钥
password = [1704953, 968245, 778054, 778054, 1742841, 1573398, 1742841, 778054, 544638] # 密文
temp = [pow(i, key[1], key[0]) for i in password] # 解密算法, 相当于 i ** key[1] % key[0]
# >>> temp
# [23, 9, 14, 14, 5, 18, 5, 14, 4]
# 你会发现每个数字都在1~26之间, 换成小写字母试试
result = [chr(96 + i) for i in temp] # 每个值增加96以后就是对应字母的ASCII值
print(''.join(result))
得到结果: winnerend, 根据源代码提示, 下一关地址是 winnerend.html
第二十一关(winnerend.html)
照样查看源代码。。。<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Challenge never end.</title>
</head>
<body bgcolor="#E8F9E8">
<h1>Python——鱼C闯关。第21关.</h1>
<hr>
<p>You win.</p>
<p>gift key: A6105C0A611B41B08F1209506350279E</p>
<hr>
Tip:
你知道python怎么压缩字符串吗?
<!-- Tip:b'x\x9c\xf3u1U\xc8OSP\xcf,\xcf\xccSWH\xccKQHIM\xceOI\x05\t\xa6g\xa6\x95(d\xa7V\xea\x01\x00\xdb\x91\x0c\x0e'-->
</body>
</html>
Python 如何压缩字符串? 用zlib模块, 将Tip里的字符串复制下来, 解压:import zlib
print(zlib.decompress(b'x\x9c\xf3u1U\xc8OSP\xcf,\xcf\xccSWH\xccKQHIM\xceOI\x05\t\xa6g\xa6\x95(d\xa7V\xea\x01\x00\xdb\x91\x0c\x0e'))
MD5 of 'iwin' and decode of gift key.
中文翻译: ('iwin' 和 gift key 的解码结果) 的 MD5
应该是作为gift key, 随便找一个MD5解密的网站, 得到结果: yes
把它和'iwin'拼起来, 变成'yesiwin'后, 算MD5import hashlib
a = hashlib.md5()
a.update('yesiwin')
print(a.hexdigest().upper())
得到结果: 7AB0F4EF2F04946B64CFAA8B722E22CC
这就是最终的gift key
Challenge never end.
</过关攻略>
|
评分
-
查看全部评分
|