原文連接:西郵Linux興趣小組2014級免試挑戰題 php
又到了小組納新的季節^_^,時間過的真快! 想起去年這會兒本身作免試題的時候根本找不着北@_@ 有幸今年可以在這裏和你們分享免試挑戰題,也正如咱們的納新宣傳語:"在這裏,讓每個意想不到成爲意料之中"。html
免試題共有設五關,分別由小組13級成員:郭遺歡、李林翰、高樸、王博、王偉豪 五位同窗負責出的,在此向他們付出的辛苦表示感謝!python
計算機的世界是從0和1開始的,正如前兩年的免試題同樣,都是用一大串的01開頭,雖然今年的免試題並非這樣,但幾乎每一關都有01的身影~_~。免試題旨在發散同窗們的思惟,運用計算機方面的基礎知識,挑戰通關,超越自我 !!下面是前兩年的免試題連接:linux
2012級免試題: 西郵Linux小組免試題揭祕算法
2013級免試題: 西郵Linux興趣小組13級納新免試題淺析vim
下面由博主來簡單分析一下今年的免試題,因爲能力有限,有啥不夠嚴謹之處歡迎你們留言交流~windows
【 第一關】微信
首先是小組微信公衆號(xiyoulinux)上推出了免試題的最新動態,給的是一個連接:orz.xiyoulinux.org。打開後發現是一個僞造的靜態頁面(下圖),之因此說是僞造的,是由於小組官網是www.xiyoulinux.org,並且頁面都同樣,明顯是個克隆品。app
隨便點了幾下,發現上面的連接都失效了,查看一下網頁源碼,啥都沒有提示。注意到推送消息上有明顯的這麼一句話:「小夥伴們這邊瞧 <img src="一張圖"/>」結合給的這個頁面,多是在圖片裏藏了啥吧,試試看咯~將圖片下載下來,挺大的,大概有6M,用vim打開這個sign.png文件,往下看看,發現最後面藏了一堆\xXX的字符串:
工具
是hex格式的字符串,貌似後面的都是\x34\x38\x39之類的,複製前面一部分出來,找個在線的編碼解碼工具(http://bianma.911cha.com/)一下看看,在文本格式裏發現了些貓膩:
注意到開頭的兩個字母:「QR」。QR是什麼玩意?百度搜一下看看:
發現是二維碼,也就是說QR後面的應該是一個二維碼。繼續分析後面的一堆數字:4948...,容易發如今ASCII碼中,ASCII碼爲48的對應字符是0,49對應的是1.而在二維碼中只有黑和白,因此0和1應該對應這兩種顏色。如今,根據上面的想法試試:
將sign.png圖片末尾\xXX格式的字符串複製到hex.txt,用python寫個簡單的腳本處理下:
#!/usr/bin/env python # coding=utf-8 import binascii # 將\xXX字符串轉換爲ASCII字符串 f = open('hex.txt') str = (str(f.readline())).replace('\n','') f.close() list = [] for i in str[12:].split('\\x'): ascii = binascii.a2b_hex(i) list.append(ascii) str1 = ''.join(list) # 將ASCII字符串轉換成0,1的字符 i = 0 bin = [] while i < len(str1): bin_num = "%c" % int(str1[i:i+2]) bin.append(bin_num) i += 2 bin_str = ''.join(bin) print 'len(bin_str)=%d' % len(bin_str) print 'bin_str=%s' % bin_str
上面的腳本運行後結果以下:
長度是625,正好是25x25的方正,找一個簡單的二維碼看一下格式就知道上面的分析是對的了^_^,下面就開始轉換成二維碼了,將上面的bin_str保存成qr_bin.txt,用python寫個腳本(因爲以前是每一個數字生成一個像素點,發現二維碼過小,因此將每一個數字生成4個像素點):
#!/usr/bin/env python # coding=utf-8 import Image MAX = 25 pic = Image.new("RGB",(MAX*2, MAX*2)) f = open('qr_bin.txt') str = str(f.readlines()) f.close() i = 2 for y in range (0,MAX): for x in range (0,MAX): if(str[i] == '1'): pic.putpixel([2*x,2*y],(0, 0, 0)) pic.putpixel([2*x+1,2*y],(0, 0, 0)) pic.putpixel([2*x,2*y+1],(0, 0, 0)) pic.putpixel([2*x+1,2*y+1],(0, 0, 0)) else: pic.putpixel([2*x,2*y],(255,255,255)) pic.putpixel([2*x+1,2*y],(255,255,255)) pic.putpixel([2*x,2*y+1],(255,255,255)) pic.putpixel([2*x+1,2*y+1],(255,255,255)) i = i+1 pic.show() pic.save("qr_code.png")
掃描二維碼獲得的結果是「never_give_up.php?key=value」。明顯是個連接,訪問這個連接發現沒反應。看看這個連接,應該是要求找到key、value啥的。可能還有信息沒有找到,打開以前的圖片發如今\xXX字符串的上面還有一段明顯的base64編碼的字符串:「a2V5P3ZhbHVlP0gzMTkuNDpJNTYxLzEyMw==」,找個在線的編碼一下,獲得「key?value?H319.4:I561/123」看到了key和value,後面的就應該有這些信息吧。關鍵是,這個「H319.4:I561/123」是啥?呵呵,這會兒,就得考考常識了~~去圖書館借過書的同窗可能就有意識了,這就是個索書號!!在圖書館官網上查了下,是本《莎士比亞十四行詩》,一共有四本。
莫非在書裏有標記啥的?有個key、value?這是個坑麼@_@?仔細想一想,書上的統一編號(ISBN號)不就是個鍵-值對麼!!固然,能想到這個,也是智力思惟啊。替換key和value,訪問連接:http://orz.xiyoulinux.org/never_give_up.php?ISBN=978-7-5135-1730-0 成功跳到第二關的頁面^_^
【 第二關】
網頁迷宮,有點意思哈,點進去試試,這尼瑪分支咋越點越多,每一個連接下面還有個0或者1,仍是黑體加粗的,看來上面圖片上說的很重要啊!既然是迷宮,就是要找到終點的那個出口嘛,固然走的路徑不少,那估計也只有一個纔是正確的吧。若是用0或者1表示通路或者障礙的話,點幾個連接後發現不對:存在對應多個連接的狀況哎。迷宮的經常使用算法是深度優先,廣度優先等等。這些算法就是求最短路徑的。因此,嘗試着跑跑吧~~用深度優先試試發現不對。改用廣度優前後跑了一分多鐘發現能夠到達終點:888888.html,下面是python寫的腳本:
#!/usr/bin/env python # coding=utf-8 import re import urllib from collections import deque queue = deque() visited = set() url = '101223.html' re_href = re.compile('href="(\d+\.html)"') queue.append(url) cnt = 1 while queue: url = queue.popleft() visited = visited | {url} print(str(cnt) + ' Running: ' + url), cnt += 1 urlop = urllib.urlopen('http://lewin.aliapp.com/'+url) try: data = urlop.read().decode('utf-8') except: continue for x in re_href.findall(data): if (x not in visited) and (x not in queue): queue.append(x)
可是,到達888888.html頁面後,發現還須要提交key,聯想到去年與這相似的題,就算手動點到的終點,沒有key不是白費的麼?是否是有種想剁手的感受!!好吧,不是說頁面上的數字很重要麼,所有記錄下來吧,稍微改一下上面的代碼:
#!/usr/bin/env python # coding=utf-8 import re import urllib from collections import deque queue = deque() visited = set() bin = [] url = '101223.html' re_href = re.compile('href="(\d+\.html)"') re_bin = re.compile('<h1>(\d)') queue.append(url) cnt = 1 while queue: url = queue.popleft() visited = visited | {url} print(str(cnt) + ' Running: ' + url), cnt += 1 urlop = urllib.urlopen('http://lewin.aliapp.com/'+url) try: data = urlop.read().decode('utf-8') except: continue try: bin_num = re_bin.search(data).group(1) print bin_num bin.append(bin_num) except: print '\nMaybe got the last!' break for x in re_href.findall(data): if (x not in visited) and (x not in queue): queue.append(x) str = ''.join(bin) print "\nbin_str= %s" % str
跑出來是下面的結果,將沒一個頁面的數字加起來又是一個長長的01字符串:
莫非又要進行啥轉換?先試試直接提交看看吧,把這個長字符串提交,發現竟然直接挑到下一關^_^,看來沒啥要處理的。
【 第三關】
第三關的頁面上有兩張同樣的圖片:
查看一下網頁源碼,也沒發現啥的,看看URL(http://www.geekgao.org/new/guess.html)注意到guess,那是叫咋猜啥呢?先把這兩張圖片down下來看看吧。既然是兩張同樣的圖片確定有啥區別,用binwalk(ps:binwalk是一個強大的文件格式分析工具,見FreeBuf介紹)分析一下這兩張圖片:
呵呵,第一張圖片結尾藏了個zip文件,還藏了個rar文件,解壓zip壓縮包:unzip new.png 生成了一個???.txt文件,在linux下中文亂碼,放到windows下能夠看到「新建文本文檔.txt」,看了下大小,竟然是0,那就啥也沒有咯,再看看那個rar文件吧,解壓:unrar x new.png 提示須要密碼,看來須要找密碼了。不是還有一張對比的圖片麼,可是發現沒藏啥的。看到上面兩圖片的Zlib數據包(ps:zlib是一種數據壓縮的格式,在圖片中存儲圖片像素點的數據塊),經過神器Stegsolve(ps:Stegsolve是圖片通道查看器,圖片隱寫必備工具,下載)來分析一下張兩張圖片的IDAT數據塊吧。對比IDAT塊的CRC(數據塊校驗和),發現有兩張圖片中有明顯的的兩個數據塊不同:
那就是像素點有不一樣了,用PS試試?不太會唉,好吧,寫個python腳本對比一下像素點吧:
#!/usr/bin/env python # coding=utf-8 from PIL import Image list = [] img1 = Image.open("new2.png") img2 = Image.open("new.png") img1_array = img1.load() img2_array = img2.load() count = 0 for j in range(527): for i in range(399): if (img1_array[i,j]) != (img2_array[i,j]): print i, j, img1_array[i,j],img2_array[i,j] list.append(str(i)) list.append(str(j)) count += 1 print 'count= %d' % count print 'pwd = '+''.join(list)
分析的結果以下,竟然有20個不一樣的像素點(以後用PS之類的在放大以後發現也能看見圖片的小點點~_~):
將各點的座標鏈接起來以後,就是上面的pwd了,好吧,把這個字符串當密碼來解壓那個含有rar文件的圖片,發現解壓成功。至此第三關算是解出來了~~
在下一篇的博客中將繼續分享:西郵Linux興趣小組2014級免試挑戰題(續)