Pwnable.kr学习之coin1

考察知识点:

1.python基本编程;

2.远程linux服务器目录/tmp的利用;

3.二分查找算法

解题过程:

a.按照提示,nc pwnable.kr 9007连接服务器,服务器返回游戏玩法提示信息,即根据N(总数量)和C(测试次数)寻找一堆球里面一个重量jiao小的球(重量为9,其余重量为10),时间限制为30秒;

b.显然,使用二分法查找,函数结构为迭代,利用pwntools编程测试;

c.发现从远程终端运行exp,查找过程比较慢(这个情况程序在玩法提示信息中也有说明),可以利用linux系统的/tmp目录本地执行exp;题目未给远程账户,因此,使用其他题目提供的账户如:col@pwnable.kr,使用下面的命令将exp上传到服务器/tmp目录:

scp -P 2222 coin_exp.py col@pwnable.kr:/tmp

d.上传后通过col账户登录系统(ssh col@pwnable.kr -p2222),进入/tmp 目录,输入ls查看上传文件,发现没有权限,不影响, 直接运行python coin_exp.py,得到flag。

代码如下:

from pwn import *
global c #每次游戏允许猜的次数
global t #每次游戏目标球的编号,从0开始
def check(x,y):
    #x:区间的开始编号
    #y:区间的末尾编号
    global c
    global t
    c=c+1
    print "checking "+str(x)+","+str(y)
    if(x==y):
        #当当前区间只剩一个球,一定是目标球
        t=x    
        return x
    if(c==C-1):
        #提示这是本轮最后一次猜测,编程习惯,没什么用
        print "No more chances!"    
    P=(x+y)/2
    #区间中点
    s=""
    #s:区间左半部分  
    r=0
    #r:保存作伴部分球的总重量
    for i in range(x , P+1):
        s=s+str(i)+" "
    print s
    R=(P-x+1)*10
    #R:如果目标球不在左半部分,左半部分的重量应该是这些    
    p.sendline(s)
    r=int(p.recv())    
    #显示左半部分真实重量
    print "res="+str(r)
    print "R="+str(R)
    if(R!=r):
    #如果目标球在左半部分
        check(x,P)
    else:
    #如果目标球不在左半部分

        check(P+1,y)
if __name__ == "__main__":
    p=remote('pwnable.kr','9007')
    print p.recv()
    time.sleep(3)
    while(1):
        inf = p.recv()
        print inf        
        N=int(inf.split(' ')[0].split('=')[1])    
        C=int(inf.split(' ')[1].split('=')[1])
        #print "N="+str(N)
        #print "C="+str(C)
        c=0
        t=-1
        check(0,N-1)
        print "target="+str(t)
        #print "send t=:"+str(t)
        p.sendline(str(t))
        u=p.recv()        
        #print "recev:"+u
        if(len(u)<10):
            #因为系统在收到目标球时,不会直接返回correct,而是返回重量9,再返回Correct!因此,在只剩两球情况中,当目标球是第一个球时,check会接受返回的重量9,而当目标球是b时,在check中,因为只剩一个球直接返回结果b,所以需要接收一次9,再发送目标球编号,再接收字符串 "Correct!(n)"        
            #print "t="+str(t)
            #print "send t=:"+str(t)
            p.sendline(str(t))
            u=p.recv()        
            print "recv:"+u
                        
            
        #print p.recvuntil("N=")
        #print "recved:"+p.recv()        
        inf=""
        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值