关卡地址
解决方案:
思路:
这一关图片中是曲奇饼干,左下角图片是不是有点熟悉?是第四关啦!
查看源代码并没有什么提示。
但是!根据cookie
可以联想到什么?对!就是浏览器缓存。
通过浏览器开发者工具查看cookie
后,可以得到如下提示:
you+should+have+followed+busynothing…
在第四关,我们请求的是:http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=
这里需要将nothing
替换为busynothing
,并且收集cookie
中info
的值。
之后得到BZh91AY
开头的经过url编码的字符串,是不是又有点熟悉?不熟悉的请回顾第八关。
使用python在解码时会有小问题:
OSError: Invalid data stream
在解码前将+
替换为%20
可以解决该问题。
解码后得到提示:
is it the 26th already? call his father and inform him that “the flowers are on their way”. he’ll understand.
这句话信息量有点大,26号暗示第十五关,call his father
则暗示第十三关,Mozart的父亲是Leopold(注意L大写)。
给Leopold打电话之后得到:
555-VIOLIN
访问violin.html
得到如下提示:
no! i mean yes! but ../stuff/violin.php.
替换url之后访问,得到的是一张Leopold的照片,及:
it’s me. what do you want?
额。。。对,and inform him that “the flowers are on their way”
将cookie
中info
的值设置为:”the flowers are on their way”,并重新请求。Leopold会回复你:
oh well, don’t you dare to forget the balloons.
所以下一关地址是:balloons.html
代码:
url='http://www.pythonchallenge.com/pc/def/linkedlist.php?busynothing='
param='12345'
import urllib.request
import http.cookiejar
cj=http.cookiejar.CookieJar()
cookie_handler=urllib.request.HTTPCookieProcessor(cj)
opener=urllib.request.build_opener(cookie_handler)
urllib.request.install_opener(opener)
import re
pattern=re.compile("the next busynothing is (\\d+)")
outstr=[]
for i in range(400):
resp=urllib.request.urlopen(url+param)
cnt=resp.read().decode('utf-8')
# print("request %4d url: %s\nresponse: %s" %(i,url+param,cnt))
outstr.append(list(cj)[0].value)
try:
param=pattern.search(cnt).group(1)
except:
print("param %s, response: %s" %(param,cnt))
if cnt == "Yes. Divide by two and keep going.":
try:
tmpParam=str(int(int(param)/2))
param=tmpParam
continue
except:
break
break
cookieStr=''.join(outstr)
print(cookieStr)
# cookieStr='BZh91AY%26SY%94%3A%E2I%00%00%21%19%80P%81%11%00%AFg%9E%A0+%00hE%3DM%B5%23%D0%D4%D1%E2%8D%06%A9%FA%26S%D4%D3%21%A1%EAi7h%9B%9A%2B%BF%60%22%C5WX%E1%ADL%80%E8V%3C%C6%A8%DBH%2632%18%A8x%01%08%21%8DS%0B%C8%AF%96KO%CA2%B0%F1%BD%1Du%A0%86%05%92s%B0%92%C4Bc%F1w%24S%85%09%09C%AE%24%90'
import codecs
import urllib.parse
info=urllib.parse.unquote_to_bytes(cookieStr.replace('+','%20'))
msg=codecs.decode(info,'bz2').decode('utf-8')
print(msg)
import xmlrpc.client
serverUrl="http://www.pythonchallenge.com/pc/phonebook.php"
serverProxy=xmlrpc.client.ServerProxy(serverUrl)
print(serverProxy.phone('Leopold'))
url='http://www.pythonchallenge.com/pc/stuff/violin.php'
cookie=list(cj)[0]
cookie.value="the flowers are on their way"
cj.set_cookie(cookie)
resp=urllib.request.urlopen(url).read().decode('utf-8')
print(resp)
PS src\static> python .\Code\Python\Challenge017.py
$url='http://www.pythonchallenge.com/pc/def/linkedlist.php?busynothing='
$param="12345"
$pattern=[regex]"the next busynothing is (\d+)"
[string]$cookieStr=""
for ($i=0; $i -lt 400; $i++) {
$resp = (Invoke-WebRequest -Uri $url+$param -SessionVariable session | Select-Object -ExcludeProperty Content).Content
$cookieStr+=$session.Cookies.GetCookies($url)[0].Value
$match = $pattern.Match($resp)
if ($match.Success) {
$param = $match.Groups[1].Value
} else {
[System.Console]::WriteLine($("param: {0}, resp: {1}" -f $param,$resp))
if ($resp -eq "Yes. Divide by two and keep going.") {
$param=$param/2
continue
}
break
}
}
$cookieStr
# $cookieStr="BZh91AY%26SY%94%3A%E2I%00%00%21%19%80P%81%11%00%AFg%9E%A0+%00hE%3DM%B5%23%D0%D4%D1%E2%8D%06%A9%FA%26S%D4%D3%21%A1%EAi7h%9B%9A%2B%BF%60%22%C5WX%E1%ADL%80%E8V%3C%C6%A8%DBH%2632%18%A8x%01%08%21%8DS%0B%C8%AF%96KO%CA2%B0%F1%BD%1Du%A0%86%05%92s%B0%92%C4Bc%F1w%24S%85%09%09C%AE%24%90"
# [System.Web.HttpUtility]::UrlDecodeToBytes 可以将'+'转换为' ',故注释掉
# $cookieStr=$cookieStr.Replace('+','%20')
$path=".\\Data\\017"
. .\Code\PowerShell\helper.ps1
New-Dir -Dir $path
$cookieFile=$path+"\\cookie.bz2"
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web")
Write-BinaryFile -Filename $cookieFile -Data $([System.Web.HttpUtility]::UrlDecodeToBytes($cookieStr))
Write-Output $(.\Code\PowerShell\bin\bzip2.exe -d -k -c $cookieFile)
$serverUrl="http://www.pythonchallenge.com/pc/phonebook.php"
Invoke-XmlRpcRequest -ServerUri $serverUrl -MethodName "phone" -Params "Leopold"
$url='http://www.pythonchallenge.com/pc/stuff/violin.php'
$cookie=[System.Net.Cookie]::new("info","the flowers are on their way")
$webSession=[Microsoft.PowerShell.Commands.WebRequestSession]::new()
$webSession.Cookies.Add($url,$cookie)
$(Invoke-WebRequest -Uri $url -WebSession $webSession | Select-Object -ExcludeProperty Content).Content
PS src\static> .\Code\PowerShell\Challenge017.ps1
package main
import(
"fmt"
"regexp"
"net/http"
"io/ioutil"
"strings"
"strconv"
"github.com/kolo/xmlrpc"
)
func (c *Challenge) Challenge017() {
url := "http://www.pythonchallenge.com/pc/def/linkedlist.php?busynothing="
param := "12345"
pattern := regexp.MustCompile("the next busynothing is (\\d+)")
var cookie *http.Cookie
outstr := ""
for i := 0; i < 400; i++ {
resp, err := http.Get(url+param)
if err != nil {
fmt.Printf("request %s%s err[%v]\n",url, param, err)
break
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("request %s%s err[%v]\n",url, param, err)
break
}
content := string(body)
temParam:=pattern.FindStringSubmatch(content)
if len(temParam) != 2 {
fmt.Printf("param: %s, response: %s\n",param, content)
if strings.Compare(content, "Yes. Divide by two and keep going.") == 0 {
intParam, err := strconv.Atoi(param)
if err == nil {
param = string(intParam/2)
continue
}
}
break
} else {
param=temParam[1]
}
cookie = resp.Cookies()[0]
outstr += cookie.Value
}
cookieFile := ".\\Data\\017\\cookie.bz2"
msg := bz2Decode(cookieFile)
fmt.Println(msg)
client, err := xmlrpc.NewClient("http://www.pythonchallenge.com/pc/phonebook.php", nil)
if err != nil {
fmt.Println("Can't create client: ", err)
}
defer client.Close()
var result string
client.Call("phone", "Leopold", &result)
fmt.Println(result)
url = "http://www.pythonchallenge.com/pc/stuff/violin.php"
httpClient := &http.Client {}
req, err := http.NewRequest("POST", url, nil)
req.Header.Set("Cookie", "info=the flowers are on their way")
resp, err := httpClient.Do(req)
if err != nil {
fmt.Printf("do post err![%v]",err)
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("post %s err![%v]", url,err)
} else {
fmt.Println(string(data))
}
}
PS src\static> .\Code\Go\Challenge.exe -l 017