pwnable.kr coin1

看一下题目
在这里插入图片描述
连上去看一下

	---------------------------------------------------
	-              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=536 C=10

参考了一下别人的思路,大概意思是说

一堆硬币,有一个假币,重量为9,而其他为10,要通过给定的C次机会内找到假币。
一共要在30s内找到100个假币,也就是完成100次游戏,最终会给出flag。

二分法处理就行了,又是一道coding。因为网络延迟的问题,所以我们不使用远程连接,
直接用其他题目的账号登录上去,在/tmp目录下写个py脚本。

但正在我想去写脚本的时候
在这里插入图片描述
已经连了一个小时了,死活连不上,连上了刚cd 到temp目录下,又卡住了,淦!
今晚看来是不能完成了,先放一下别人的解题思路吧

import socket
import sys
import re

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", 9007))

def get_numbers(ss, ee):
        str_list = []
        for n in range(ss, ee):
                str_list.append(str(n))
        return " ".join(str_list)

start = 0
while True:
        data = s.recv(1024)
        print data
        pattern1 = re.compile("^N=([0-9]*) C=([0-9]*)$")
        match1 = pattern1.match(str(data))
        pattern2 = re.compile("^([0-9]*)$")
        match2 = pattern2.match(str(data))

        if match1:
                end = int(match1.group(1))
                fr = (0,end/2)
                sr = (end/2+1, end)
                s.send(get_numbers(fr[0], fr[1])+"\n")
        elif match2 and len(match2.group(1)) > 0:
                w = int(match2.group(1))
                if (fr[1] - fr[0])*10 == w:
                        fr = (sr[0], (sr[0]+sr[1])/2+(sr[0]+sr[1])%2)
                        sr = (fr[1], sr[1])
                else:
                        sr = (fr[1], fr[1])
                        fr = (fr[0], (fr[0]+fr[1])/2+(fr[0]+fr[1])%2)
                        sr = (fr[1], sr[1])

                s.send(get_numbers(fr[0], fr[1])+"\n")
               
get_numbers用于生成索引序列,比如2 3 4 5,满足格式需求。后面就是简单的
正则匹配,取出服务器的结果,if/else分支根据当前的weight总和判断假币在左侧
还是右侧,如此二分查找下去最终可以找到假币索引。

作者-----:https://r00tk1ts.github.io/2018/03/10/coin1/

#!/usr/bin/python
__author__ = "TaQini"
 
from pwn import *
import re
 
def getNC():
	r = target.readline() #number and changes
	NC = re.findall("[0-9]+",r)
	return int(NC[0]), int(NC[1])
 
def guess(start, end):
    coin = ""
    for i in xrange(start, end+1):
        coin += str(i) + " "
    # print "coin " + coin
    target.sendline(coin)
    weight = target.read()
    # print "weight " + str(weight)
    return weight
 
def binsearch():
	for i in range(100):
		N, C = getNC()
		cnt = 0
		# print "N= " + str(N) + " C=" + str(C)
		Left = 0
		Right = N - 1
		while (Left <= Right):
			Mid = (Left + Right)/2
			# print "guess " + str(Left) + "-" + str(Mid)
			cnt += 1
			if cnt > C:
				# print "Hit!"
				weight = guess(Left,Mid)
				break
			else:
				weight = guess(Left,Mid)
				# print "trial= " + str(cnt)
				# print "and C= " + str(C)
				if (eval(weight) + 1) % 10:  # fake coin not here
					Left = Mid + 1
				else:
					Right = Mid
		print "hit!",(i),
 
target = remote("127.0.0.1",9007)
target.read() #rule of game
binsearch()
print target.read()

作者----https://blog.csdn.net/SmalOSnail/article/details/53129001

import time
from pwn import *

conn = remote('0', 9007)
conn.recv(10024)
for _ in range(100):
    line = conn.recv(1024).decode('UTF-8').strip().split(' ')
	  print(line)
    n = int(line[0].split('=')[1])
    c = int(line[1].split('=')[1])
    left = 0
    right = n

    for _ in range(c):
        guess = ' '.join(str(left) for left in range(left, int((left+right)/2)))
        conn.sendline(guess)
        output = int(conn.recv(1024).decode('UTF-8').strip())
        if (output % 10 == 0):
            left = int((left+right)/2)
        else:
            right = int((left+right)/ 2)
    conn.sendline(str(left))
    print(conn.recv(1024).decode('UTF-8'))
print(conn.recv(1024).decode('UTF-8'))
conn.close()                 

作者----https://www.rootnetsec.com/pwnable.kr-coin1/ (讲解了一些算法思路)

溜了溜了
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值