wdnmd B64 [攻防世界]

#problem.py
#!/usr/bin/python2
#from flag import flag
from base64 import b64decode
from SocketServer import ThreadingTCPServer
from sys import argv
from binascii import hexlify, unhexlify
import SocketServer
import os
flag = 'flag{123456789}'#本地调试
N = 8
MAX_TRIES = 1024
PAD = 64

welcome = "Welcome! :-)\n"
menu = "What would you like to do:\n\t1: supply encoded input,\n\t2: tell me my secret\n> "

def gen_secret():
    return os.urandom(N)

def crypt(s1, s2):
    return "".join(map(lambda c: chr(((ord(c[0])^ord(c[1]))+PAD)%256), zip(s1,s2)))

b64chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"
def decode(s, secret):
    enc = ""
    s = crypt(s, secret)
    
    for c in s:
        if c in b64chars:
            enc+=c

    if len(enc) % 4 == 1:
        enc = enc[:-1]

    while len(enc) % 4 != 0:
        enc+="="

    return b64decode(enc)

class B64Handler(SocketServer.BaseRequestHandler):
    def setup(self):
        self.tries = 0
        self.secret = gen_secret()

    def handle(self):
        self.request.send(welcome)
        for i in range(MAX_TRIES):
            self.request.send("Round number: {}\n{}".format(i, menu))
            if self.request.recv(2)[0] == "1":
                self.request.send("What would you like me to decode?\n> ")
                answer = self.request.recv(len(self.secret))
                decoded = decode(answer, self.secret)
                self.request.send("Alright, here is your answer: {}\n".format(decoded))

            else:
                self.request.send("Alright, what is my secret (hex encoded)?\n> ")
                answer = self.request.recv(2*len(self.secret)+1).rstrip()
                if answer==hexlify(self.secret):
                    self.request.send("Well done, here is your flag: {}\n".format(flag))
                else:
                    self.request.send("This was not what I was looking for. :-(\n")
                break

        self.request.send("Bye!\n")

def main():
    SocketServer.ThreadingTCPServer.allow_reuse_address = True
    if len(argv) < 2:
        print("Usage: {} <PORT>".format(argv[0]))
    else:
        LOCAL_PORT = int(argv[1])
        s = SocketServer.ThreadingTCPServer(("", LOCAL_PORT), B64Handler)
        try:
            s.serve_forever()
        except KeyboardInterrupt:
            print("shutting down")
            s.shutdown()
            s.socket.close()

if __name__ == "__main__":
    main()

  

 

可以看到这个server拥有两个功能,一个是将你发送过去的字符和secret运算 ,如果有符合base64字符的就返回

另一个是发送hex形式的secret 然后server返回flag

这道题有个小技巧

需要让对方返回最少四个字节才能根据一位判定,因为只有超过四个字节才不会被丢弃字符

from pwn import *
import string
list1 = string.printable
import os
#context.log_level = 'debug'

p = remote('192.168.1.1',8088)#服务ip和端口

p.recvuntil('> ')
p.sendline('1')
p.recvuntil('> ')
p.send('0'*8)
p.recvuntil('answer: ')
str1 = p.recvline()[:-1]

while len(str1)<4:
    p.close()
    p = remote('192.168.170.1',8088)
    p.recvuntil('> ')
    p.sendline('1')
    p.recvuntil('> ')
    p.send('0'*8)
    p.recvuntil('answer: ')
    str1 = p.recvline()[:-1]
len_num = len(str1)
#print 'str1 = ',repr(str1)
base_enc = str1.encode('base64').split('=')[0]
#print base_enc
flag = list('11111111')
str3 = ''
for i in range(8):
    p.sendline('1')
    str3 = '0'*i+'\x00'+'0'*(7-i)
    p.send(str3)
    p.recvuntil('answer: ')
    str2 = p.recvline()[:-1]
    if len(str2)<len_num:
    	flag[i]='0'
#print flag
test_6 = 0
while "".join(flag).count('0')<6:
    for i in range(8):
        p.sendline('1')
        str3 = '0'*i+os.urandom(1)+'0'*(7-i)
        p.send(str3)
        p.recvuntil('answer: ')
        str2 = p.recvline()[:-1]
        if len(str2)<len_num:
    	    flag[i]='0'
#print flag
index_1 = flag.index('1')
flag[index_1] = '0'
str3 = '00000000'
for i in range(0xff):
    mid = str3[:index_1]+chr(i)+str3[index_1+1:]
    p.sendline('1')
    p.send(mid)
    p.recvuntil('answer: ')
    str2 = p.recvline()[:-1]
    if len(str2)==5:
        #print '5555555555555555'
    	break
#print 'mid =',repr(str2)
index_2 = flag.index('1')
for i in range(0xff):
    last = mid[:index_2]+chr(i)+mid[index_2+1:]
    p.sendline('1')
    p.send(last)
    p.recvuntil('answer: ')
    str2 = p.recvline()[:-1]
    if len(str2)==6:
        #print '666666666666666666'
    	break
#print 'last =',repr(last)
#print 'str2 =',repr(str2)
#print 'b64str2 =',repr(str2.encode('base64'))
p.sendline('2')
sec = ''
for i,j in zip(last,str2.encode('base64')):
     sec += chr(((ord(j)-64)%256)^ord(i))
p.sendline(sec.encode('hex'))
p.interactive()

  

posted @ 2020-06-22 17:30  S4tan  阅读(320)  评论(0编辑  收藏  举报