pwnable.kr-coin1 简单的二分查找。

题目分析

根据所给信息

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

这题没有给我们账号,不过可以用其它的账号去连接欸,然后跑。

可以先nc这个端口看看提示:

  • 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 60 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 # counterfeit coin is third!
    [Server] Correct!

  • Ready? starting in 3 sec…

简而言之,有 n 个硬币,c 次机会,有一个硬币的重量为 9,其余为 10,请你在 c 次机会内找到这个重量为 9 的硬币,但是你要找 100 次,而且应该是有时间限制的。

其实就是二分查找,你先给它输入一半的硬币编号,如果重量不是 10 的整倍数,说明在里面,然后缩小一半的范围,如果是,那就缩小到另一半,最后它给的数据范围肯定是能找到的。

题解

pwnable.kr 有点卡说实话,所以远程连接可能没跑完就掉了,所以你得先上传脚本,然后本地连端口,这里面 /tmp 目录虽然不可读但是可写,可以在里面新建一个文件夹然后脚本上传上去,最后py直接跑。

下面是我写的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from pwn import *
context.log_level='debug'
p=remote('127.0.0.1',9007)
def recvnum():
ch=p.recv(1)
num=0
while ch=='\n':
ch=p.recv(1)
while ch.isdigit():
num=num*10+int(ch)
ch=p.recv(1)
return num

def sendp(l,r):
payload=''
for i in range(l,r+1):
payload+=str(i)+' '
p.sendline(payload[:-1])
res=recvnum()
return res%10==0
def work():
p.recvuntil(b'N=')
n=recvnum()
p.recvuntil(b'C=')
count=recvnum()
l=0
r=n
while l<r:
mid=l+r>>1
if sendp(l,mid):
l=mid+1
else:
r=mid
count-=1
for i in range(count+1):#如果找的很快需要消耗完下面的次数
sendp(l,l)

p.recvuntil(b'- Ready? starting in 3 sec... -')
for i in range(100):
work()
p.interactive()

结果:

flag:b1NaRy_S34rch1nG_1s_3asy_p3asy