Mommy, I wanna play a game!
(if your network response time is too slow, try nc 0 9007 inside pwnable.kr server)
Running at : nc pwnable.kr 9007
游戲規(guī)則如下:
---------------------------------------------------
- Shall we play a game? -
---------------------------------------------------
You have given some gold coins in your hand
however, there is one counterfeit coin among them
counterfeit coin looks exactly same as real coin
however, its weight is different from real one
real coin weighs 10, counterfeit coin weighes 9
help me to find the counterfeit coin with a scale
if you find 100 counterfeit coins, you will get reward :)
FYI, you have 30 seconds.
- How to play -
1. you get a number of coins (N) and number of chances (C)
2. then you specify a set of index numbers of coins to be weighed
3. you get the weight information
4. 2~3 repeats C time, then you give the answer
- Example -
[Server] N=4 C=2 # find counterfeit among 4 coins with 2 trial
[Client] 0 1 # weigh first and second coin
[Server] 20 # scale result : 20
[Client] 3 # weigh fourth coin
[Server] 10 # scale result : 10
[Client] 2 # coun
terfeit coin is third!
[Server] Correct!
就是在30秒內(nèi)田弥,以給定的輸入次數(shù)完成游戲 100 次涛酗, 即 100 次找到 N 枚硬幣中的 1 枚次品。
對(duì)于輸入下標(biāo)對(duì)應(yīng)的硬幣是否合格偷厦,主要看返回的weight末位數(shù)字是 0 (合格)還是 9 (含不合格)就可以了商叹;直接輸入當(dāng)然不現(xiàn)實(shí),可以簡(jiǎn)單地用二分法處理沪哺,連接服務(wù)器并跑出 flag 沈自。人生苦短我用Python :P
這里還有一個(gè)問題酌儒,筆者一開始通過 pwn 庫寫腳本遠(yuǎn)程連接該服務(wù)器辜妓,無論怎么改進(jìn)算法,最多跑出 8 次就到 30 秒的時(shí)限忌怎。所以如果不是在服務(wù)器本地跑(HOST = 0)一般是肯定來不及的籍滴,這里網(wǎng)絡(luò)延遲的影響遠(yuǎn)遠(yuǎn)大于算法效率。
所以我們得先登錄到pwnable.kr榴啸,任選一個(gè)之前連接過的用戶登錄孽惰,到 /tmp 目錄下創(chuàng)建自己的目錄,放上腳本即可鸥印。另外由于服務(wù)器上沒有 pwn 或者 zio 庫勋功,只能手打 socket 連接:
import re
from socket import *
# func: get output str of numbers between inv
def getInv(inv):
invList = []
split = ' '
for i in range(inv[0], inv[1]):
invList.append(str(i))
return split.join(invList)
# server addr info
HOST = '0' # local at pwnable.kr
PORT = 9007
ADDR = (HOST, PORT)
BUFSIZE = 1024
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect(ADDR)
# start: [Server]: N=? C=?
startPattern = re.compile(r'^N=(\d*)\sC=(\d*)$');
# step: [Server]: ***0 (qual)
qualPattern = re.compile(r'^(\d*0)$');
# step: [Server]: ***9 (unqual)
unqualPattern = re.compile(r'^(\d*9)$');
curInv = None # current interval
preInv = None # previous interval
while True:
data = clientSocket.recv(BUFSIZE)
print data
match1 = startPattern.match(data)
match2 = qualPattern.match(data)
match3 = unqualPattern.match(data)
if match1: # match startPattern
curInv = (0, int(match1.group(1))/2)
preInv = (0, int(match1.group(1)))
print getInv(curInv)
clientSocket.send(getInv(curInv) + '\r\n') # send numbers to HOST
elif match2: # match qualPattern
preInv = (curInv[1], preInv[1])
curInv = (preInv[0], (preInv[0]+preInv[1])/2 + (preInv[0]+preInv[1])%2)
print getInv(curInv)
clientSocket.send(getInv(curInv) + '\r\n')
elif match3: # match unqualPattern
preInv = curInv
curInv = (preInv[0], (preInv[0]+preInv[1])/2 + (preInv[0]+preInv[1])%2)
print getInv(curInv)
clientSocket.send(getInv(curInv) + '\r\n')
elif 'wrong' in data or 'error' in data or 'bye' in data:
break
clientSocket.close()
最后終于能在時(shí)限內(nèi)跑出 flag ,結(jié)果如下:
...
Correct! (99)
Congrats! get your flag
b1NaRy_S34rch1nG_1s_3asy_p3asy
time expired! bye!