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()

浙公网安备 33010602011771号