PythonChallenge系列解题步骤@Skiery
Python Challenge 5
Challenge 5
题目给的线索是:pronounce it
,没有头绪,还是看看网页源码吧,果然,在源码里看到提示:
<!-- peak hell sounds familiar ? -->
em,看图是一坨绿山,def文件夹下还有一张图片是peakhell,和图中的发音相似提示?·······
好吧,我想了好久也没想起来,然后看了提示,发现是pickle模块···在源代码中看了一下,发现了一点东西:
<peakhell src="banner.p"/>
em,这个大概是我们需要用pickle去解码的文件,所以开始解题
Solution 5
代码如下:
import urllib.request
import pickle
url = "http://www.pythonchallenge.com/pc/def/banner.p"
result = pickle.load(urllib.request.urlopen(url))
运行之后发现result是一个超大的元组,按行打印看看内容:
for line in result:
print("".join([i*j for i,j in line])) #注意有时候显示会有问题,记得调宽cmd的显示宽度,不然显示会有问题
显示结果如下:
用得到的flag修改url地址,进入下一题~
Python Challenge 6
Challenge 6
除了这张图,还有一个PayPal的Donate链接可以点击,点下试试呗,结果···真的是donate链接。。
换个思路按老方法查看页面源代码吧,结果发现了提示:
<!-- The following has nothing to do with the riddle itself. I just
thought it would be the right point to offer you to donate to the
Python Challenge project. Any amount will be greatly appreciated.
-thesamet
-->
em,就是下面就是掏钱,跟解题无关,付了就行···然后又仔细看了看,发现不对,还有其他信息量:
<!-- <-- zip --> #这里这个zip不知道大家有没有发现
<head>
<title>now there are pairs</title>
<link rel="stylesheet" type="text/css" href="../style.css">
</head>
<body>
<center>
<img src="channel.jpg">
<br/>
<!-- The following has nothing to do with the riddle itself. I just
thought it would be the right point to offer you to donate to the
Python Challenge project. Any amount will be greatly appreciated.
-thesamet
-->
Solution 6
原谅我愚蠢的智商,明明找到了flag还在乱试,最终求助百度才发现,直接改url下载zip就行···解压文件中的readme发现,是一道在zip中循环访问txt的题目,并且readme.txt中给出了第一个flag是90052,有点类似peak.html那道题,所以··百度zipfile用法后后开始做吧,代码如下:
import zipfile
file_aim = zipfile.ZipFile("C://Users//Administrator//Downloads//channel.zip","r")
add_s = “”90052“
while add_s:
add_temp = file_aim.read(add_s+".txt").decode()
print(add_temp)
add_s = re.findall("is (\d+)",add_temp,re.DOTALL)[-1]
嗯,跑完之后会在46145处报错(没有用while的try except机制,大家自己改一下吧,哈哈),查看其中内容,发现add_temp = “Collect the comments”
然后自行百度一下comment相关内容,发现是zipfile模块下子函数getinfo下面的一个子函数comment,储存了zip中子文件的一个comment信息,方法如下:
zipfile.getinfo(filename).comment
所以修改之前的代码并添加,重新运行:
import zipfile
file_aim = zipfile.ZipFile("C://Users//Administrator//Downloads//channel.zip","r")
add_s = "90052"
comments = file_aim.getinfo(add_s+".txt").comment.decode()
while add_s:
add_temp = file_aim.read(add_s+".txt").decode()
comments += file_aim.getinfo(add_s +".txt").comment.decode()
print(add_temp)
add_s = re.findall("is (\d+)",add_temp,re.DOTALL)[-1]
之后就得到comments的原始数据了,然后新建一个字典记一下数:
dict_count = {}
for i in comments:
dict_count[i]= dict_count.get(i,0)+1
print(dict_count)
em,输出之后看一下,发现除了特殊符号之外,正好统计出来时oxygen,是个单词,氧气,尝试一下,bingo,进入下一道题~
PS:在comments统计之前print一下,还有一个hockey的字样,试过会发现不对,it's in the air. look at the letters.
Python Challenge 7
首先从图片格式就发现了,这个换成了png,并且图片上有一堆堆的色块,考虑,源网页和页面均没有任何提示,所以从百度python如何处理png图片开始吧
Solution 7
百度后发现,使用pillow库函数可以获得png图片信息,所以··先跑一下试试:
pip install Pillow #安装
from PIL import Image #导入图像处理模块
#方法1
import urllib.request
img = Image.open(urllib.request.urlopen("http://www.pythonchallenge.com/pc/def/oxygen.png")) #这种方法就可以打开文件了,不过在hackingnote上学到了另外一种打开方法
#方法2
import requests
from io import BytesIO
img = Image.open(BytesIO(requests.get('http://www.pythonchallenge.com/pc/def/oxygen.png').content)) #content 参数有没有似乎影响不大,有兴趣的朋友自己再查阅一下资料吧#
运行发现图片的格式是这样的:<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=629x95 at 0x30C7F98>
,最后的地址没什么意义,重要的信息主要是图片格式“RGBA”,大小:“629*95”,RGBA是按四项储存一个像素点信息的(R(red),G(greed),B(blue),A(透明度??)),再观察图像(嗯,好吧,也参考了别人的东西,哈哈),发现图中有灰条条,猜测信息量在里面,那么再看看怎么把信息提取出来吧,查证之后公式是这样的:img.getpixel(x,y)
,从图像中间画一条线,吧线上的元素都存下来,应该能获得灰度信息,尝试操作一下:
row_aim = [img.getpixel((x,img.weight/2)) for x in range(img.width)]
得到row_aim后,观察中间段数据发现,rgb相同的信息点都重复了最少7次,所以先缩短一下row_aim的信息量:
row_aim = row_aim[::7]
再筛选出灰条内的像素点(查资料及观察均可知道,灰条内的像素点RGB值应该是相等的):
row_final = [r for r,g,b,a in row_aim if r == g == b]
得到一串数字:python>>> row_final [115, 109, 97, 114, 116, 32, 103, 117, 121, 44, 32, 121, 111, 117, 32, 109, 97, 100, 101, 32, 105, 1 16, 46, 32, 116, 104, 101, 32, 110, 101, 120, 116, 32, 108, 101, 118, 101, 108, 32, 105, 115, 32, 91 , 49, 48, 53, 44, 32, 49, 49, 48, 44, 32, 49, 49, 54, 44, 32, 49, 48, 49, 44, 32, 49, 48, 51, 44, 32 , 49, 49, 52, 44, 32, 49, 48, 53, 44, 32, 49, 49, 54, 44, 32, 49, 50, 49, 93]
看起来就像ASCII码的东西,试一下~:
row_final_test = "".join(map(chr,row_final))
得到输出:smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]
,继续执行代码:
row_final_test = re.findall("[0-9]{3}",row_final_test,re.DOTALL)
row_final_flag = "".join(map(chr,map(int,row_final_test)))
得到flag为integrity,改变url后进入下一道题~
Python Challenge 8
Challenge 8
在页面里看到一个提示:where is the missing link?
页面中的图片似乎可以点击,我们尝试点进去看看,发现需要输入用户名和密码,试了admin*2发现不对,所以还是老样子,进源代码看看是什么梗,结果发现东下面两条东西:
<!--
un: 'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
pw: 'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$ \x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08'
-->
直接复制代码给un赋值发现会出现特殊符号直接输出的情况,所以我直接从网页上爬下来,然后用re.compile用正则表达式匹配抠出un和pw:
import urllib.request
import re
html = urllib.request.urlopen("http://www.pythonchallenge.com/pc/def/integrity.html").read()
raw_name = re.findall(b"\nun: '(.*?)'\n",html,re.DOTALL)[0]
raw_ps = re.findall(b"\npw: '(.*?)'\n",html,re.DOTALL)[0] #观察一下,发现字符串中\x的多了空格,所以去掉空格
raw_un_final = eval(repr(raw_name).replace('\\\\','\\'))
raw_ps_final = eval(repr(raw_ps).replace('\\\\','\\'))
#这种方法可以用urllib.request爬取得到bz2能够解密的、原始Bytes类型加密后的数据,如果decode转换成字符串后,无法重新加密为bz2可以识别的byte类型数据
得到原始的un和ps序列un_name和un_ps,准备解码:
尝试各种方法(悄悄看了教程),发现原来这是用bz2加密过的字符串,直接解密就行了(其实前面费劲心思扒原始byte信息也是因为要配合bz2解密使用)
import bz2
un = b'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
ps = b'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$ \x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08'
bz2.decompress(un)
bz2.decompress(ps)
得到最终的结果,用户名是huge,密码为file
PS:这一道题是真的心累,开始从网站上扒下来扣扣巴巴compile出来的代码扒了一堆,结果还不如手动复制粘贴,心塞······
ANYWAY:在此再次感谢开源网站(www.hackingcode.com)提供的解题步骤,不会的时候有个东西参考真是太开心啦,希望我的一些解题过程对大家有所帮助,共勉,fighting~