HGAME 2020 Week3&Week4 wp

第三周不太舒服,每天都是在床上度过的,划个水吧。
第四周就写出来一个题,也放在这里。

W3 Crypto

3. Exchange

中间人攻击。

import string
from Crypto.Util.number import inverse
from hashlib import sha256
from pwn import remote
from binascii import hexlify, unhexlify

def int2hex(i):
    hstr = hex(i)
    hstr = hstr[2:]
    return "0" + hstr if len(hstr) % 2 == 1 else hstr

L = string.ascii_letters+string.digits
sock = remote("47.98.192.231", 25258)
s = sock.recv(1024).split(b"\n")[0]
_hexdigest = s[-64:].decode()
sub = s[12:28]
print(sock.recv(1024))
Flag = True
for a in L:
    if not Flag:
        break
    for b in L:
        if not Flag:
            break
        for c in L:
            if not Flag:
                break
            for d in L:
                if not Flag:
                    break
                pre = (a+b+c+d).encode()
                hexstr = sha256(pre + sub).hexdigest()
                if hexstr == _hexdigest:
                    print(pre)
                    sock.send(pre)
                    Flag = False

sock.recvline() # b'Bob: Hi Alice, I got the second half of the flag.\n'
sock.recvline() # b'Alice: Really? I happen to have the first half of the flag.\n'
sock.recvline() # b"Bob: So let's exchange flags, :-)\n"
sock.recvline() # b'Alice: Ok, \n'
sock.recvline() # b'Alice: Ah, wait, maybe this channel is not secure, \n'
sock.recvline() # b"Alice: Let's do Key Exchange first.\n"
sock.recvline() # b'\n'
sock.sendline()
sock.recvline() # b'[INFO] : ********** STEP.1 **********\n'
sock.recvline() # b'[INFO] : Alice and Bob publicly agree to use a modulus `p` and base `g`\n'
sock.recvline() # b'\n'
p = sock.recvline() # b'Alice: p = xxx\n'
p = int(p[11:-1])
g = sock.recvline() # b'Alice: g = xxx\n'
g = int(g[11:-1])
sock.recvline() # b'\n'
sock.sendline()
sock.recvline() # b'[INFO] : ********** STEP.2 **********\n'
sock.recvline() # b'[INFO] : Alice generates her private key `a` which is a random number from the set {2, 3, ... p-2}.\n'
sock.recvline() # b'[INFO] : Bob does exactly the same: he compute his private key `b` which is taken randomly from the same set of integers.\n'
sock.recvline() # b'[INFO] : Now, Alice computes her public key `A` which is simply `g` raises to the `a`s power modulo `p`, a.k.a, `A = pow(g, a, p)`.\n'
sock.recvline() # b'[INFO] : Bob does the same: Bob computes the `B = pow(g, b, p)`.\n'
sock.recvline() # b'\n'
sock.sendline()
sock.recvline() # b'[INFO] : ********** STEP.3 **********\n'
sock.recvline() # b'[INFO] : Alice and Bob exchange their public key.\n'
sock.recvline() # b'[WARNING] : You intercepted Alice's message, which is\n'
A = sock.recvline() # b'[WARNING] : A = xxx\n'
A = int(A[16:-1])
sock.recvline() # b'[WARNING] : Do you want to modify this message? (yes/no)\n'
sock.send("yes")
sock.recvline() # b'> [WARNING] : Select a decimal number\n'
t = 2
T = pow(g, t, p)
sock.sendline(str(T))
sock.recvline() # b'> \n'
sock.recvline() # b'Alice: A = xxx\n'
sock.recvline() # b'\n'
sock.sendline()
sock.recvline() # b"[WARNING] : Again, you intercepted Bob's message, which is\n"
B = sock.recvline() # b'[WARNING] : B = xxx\n'
B = int(B[16:-1])
sock.recvline() # b'[WARNING] : Do you want to modify this message? (yes/no)\n'
sock.send("yes")
sock.recvline() # b'> [WARNING] : Select a decimal number\n'
sock.sendline(str(T))
sock.recvline() # b'> \n'
sock.recvline() # b'Bob: B = xxx\n'
sock.recvline() # b'\n'
sock.sendline()
sock.recvline() # b'[INFO] : ********** STEP.4 **********\n'
sock.recvline() # b'[INFO] : Alice takes public key of Bob (`B`), raises to, again, to the `a`s power modulo `p`, the she gets the secret value `S_a = pow(B, a, p)`.\n'
sock.recvline() # b'[INFO] : Bob also gets the secret value `S_b = pow(A, b, p)`.\n'
sock.recvline() # b'[INFO] : Right now, they have done the key exchange.\n'
sock.recvline() # b'[WARNING] : hint: does Alice and Bob share the same key?\n'
sock.recvline() # b'\n'
sock.sendline()
sock.recvline() # b'Alice: Now, we have securely shared the secret value.\n'
sock.recvline() # b"Bob: Right, let's exchange the encrypted flag!\n"
sock.recvline() # b'\n'
sock.sendline()
sock.recvline() # b'[INFO] : For the encryption, Alice compute `C_a = (m * S_a) % p`\n'
sock.recvline() # b'[INFO] : Bob does the same, `C_b = (m * S_b) % p`\n'
sock.recvline() # b'\n'
sock.sendline()
sock.recvline() # b'[WARNING] : Bob is trying to send a message to Alice, \n'
C_b = sock.recvline() # b'[WARNING] : C_b = xxx\n'
C_b = int(C_b[18:-1])
P_b = (C_b * inverse(pow(B, t, p), p)) % p
flag2 = unhexlify(int2hex(P_b))
print(flag2)
sock.recvline() # b'[WARNING] : Do you want to modify this message? (yes/no)\n'
sock.send("yes")
sock.recvline() # b'> [WARNING] : Select a decimal number\n'
C_b = (P_b * pow(A, t, p)) % p
sock.sendline(str(C_b))
sock.recvline() # b'> Alice: Great, I get the flag.\n'
C_a = sock.recvline() # b'Alice: C_a = xxx\n'
C_a = int(C_a[13:-1])
P_a = (C_a * inverse(pow(A, t, p), p)) % p
flag1 = unhexlify(int2hex(P_a))
print(flag1)
print(flag1 + flag2)

4. FeedBack

构造攻击就好啦。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from binascii import hexlify, unhexlify
from pwn import remote

pad_hex_0 = b"0" * 32

def xor(str1, str2):
    return bytes([a^b for a, b in zip(str1, str2)])

# 第一次,获取F1
sock = remote("47.98.192.231", 25147)
sock.recvline() # b"You have only 3 times to decrypt sth, then I'll give u the FLAG.\n"
sock.recvline() # b"Give me sth(hex) to decrypt\n"
sock.sendline(pad_hex_0)
E_iv = sock.recvline()[2:-1] # b'> hexstr\n'
E_iv = unhexlify(E_iv)
sock.recvline() # b"Give me sth(hex) to decrypt\n"
sock.sendline(pad_hex_0)
sock.recvline() # b'> hexstr\n'
sock.recvline() # b"Give me sth(hex) to decrypt\n"
sock.sendline(pad_hex_0)
sock.recvline() # b'> hexstr\n'
f1enc = sock.recvline()[34:-1] # b'Here is your encrypted FLAG(hex): hexflag\n'
f1enc = f1enc[:32]
f1enc = unhexlify(f1enc)
f1 = xor(f1enc, E_iv)
print(f1)

# 第二次,获取f2
sock = remote("47.98.192.231", 25147)
sock.recvline() # b"You have only 3 times to decrypt sth, then I'll give u the FLAG.\n"
sock.recvline() # b"Give me sth(hex) to decrypt\n"
sock.sendline(f1.hex())
E_f1_hex = sock.recvline()[2:-1] # b'> hexstr\n'
sock.recvline() # b"Give me sth(hex) to decrypt\n"
sock.sendline(E_f1_hex + pad_hex_0)
E_Ef1 = sock.recvline()[2:-1] # b'> hexstr\n'
E_Ef1 = unhexlify(E_Ef1)[16:]
sock.recvline() # b"Give me sth(hex) to decrypt\n"
sock.sendline(pad_hex_0)
sock.recvline() # b'> hexstr\n'
f2enc = sock.recvline()[34:-1] # b'Here is your encrypted FLAG(hex): hexflag\n'
f2enc = f2enc[32:64]
f2enc = unhexlify(f2enc)
f2 = xor(f2enc, E_Ef1)
print(f2)

# 第三次,获取f3
sock = remote("47.98.192.231", 25147)
sock.recvline() # b"You have only 3 times to decrypt sth, then I'll give u the FLAG.\n"
sock.recvline() # b"Give me sth(hex) to decrypt\n"
sock.sendline(f1.hex())
E_f1_hex = sock.recvline()[2:-1] # b'> hexstr\n'
sock.recvline() # b"Give me sth(hex) to decrypt\n"
sock.sendline(E_f1_hex + pad_hex_0)
E_Ef1 = sock.recvline()[2:-1] # b'> hexstr\n'
E_Ef1 = unhexlify(E_Ef1)[16:]
sock.recvline() # b"Give me sth(hex) to decrypt\n"
sock.sendline(pad_hex_0 + hexlify(xor(E_Ef1, f2)) + pad_hex_0)
E_Ef2 = sock.recvline()[2:-1] # b'> hexstr\n'
E_Ef2 = unhexlify(E_Ef2)[32:]
f3enc = sock.recvline()[34:-1] # b'Here is your encrypted FLAG(hex): hexflag\n'
f3enc = f3enc[64:]
f3enc = unhexlify(f3enc)
f3 = xor(f3enc, E_Ef2)
print(f3)
print(f1 + f2 + f3)

W4 Crypto

2. ToyCipher

z3就完事了。

from z3 import *

def rotL(x, nbits, lbits):
    mask = 2**nbits - 1
    return (x << lbits%nbits) & mask | ( (x & mask) >> (-lbits % nbits) )


def rotR(x, nbits, rbits):
    return rotL(x, nbits, -rbits%nbits)


def keySchedule(masterkey):
    roundKeys = [ ( rotR(masterkey, 64, 16*i) % 2**16 ) for i in range(12) ]
    return roundKeys


def f(x, roundkey):
    return rotL(x, 16, 7) ^ rotL(x, 16, 2) ^ roundkey


def ToyCipher(block, mode='enc'):
    '''Feistel networks'''
    roundKeys_ = ROUNDKEYS
    if mode == 'dec':
        roundKeys_ = roundKeys_[::-1]

    L, R = (block >> 16), (block % 2**16)
    for i in range(12):
        _R = R
        R = L ^ f( R, roundKeys_[i] )
        L = _R

    return (R << 16) | L


def pad(data, blocksize):
    pad_len = blocksize - (len(data) % blocksize)
    return data + bytes( [pad_len] * pad_len )


def unpad(data, blocksize):
    pad_len = data[-1]
    _data = data[:-pad_len]
    assert pad(_data, blocksize)==data, "Invalid padding."
    return _data


def encrypt_intvec(plaintext):
    '''ECB mode'''
    plaintext = pad(plaintext, BLOCKSIZE)
    ciphertext = []
    for i in range( len(plaintext) // BLOCKSIZE ):
        block = plaintext[i*BLOCKSIZE:(i+1)*BLOCKSIZE]
        block = int.from_bytes(block, byteorder='big')
        E_block = ToyCipher(block)
        ciphertext.append(E_block)
    return ciphertext


def decrypt(ciphertext):
    '''ECB mode'''
    plaintext = b''
    for i in range( len(ciphertext) // BLOCKSIZE ):
        block = ciphertext[i*BLOCKSIZE:(i+1)*BLOCKSIZE]
        block = int.from_bytes(block, byteorder='big')
        D_block = ToyCipher(block, 'dec')
        plaintext += D_block.to_bytes(BLOCKSIZE, byteorder='big')
    plaintext = unpad(plaintext, BLOCKSIZE)
    return plaintext


masterkey = BitVec("masterkey", 8 * 8)
ROUNDKEYS = keySchedule(masterkey)
BLOCKSIZE = 4
solver = Solver()
ciphertext = b'\x91a\xb1o\xed_\xb2\x8c\x00\x1b\xdfp'
enintvec = encrypt_intvec(b'just a test')
anslist = []
for i in range( len(ciphertext) // BLOCKSIZE ):
    block = ciphertext[i*BLOCKSIZE:(i+1)*BLOCKSIZE]
    block = int.from_bytes(block, byteorder='big')
    anslist.append(block)
for i in range( len(ciphertext) // BLOCKSIZE ):
    solver.add(anslist[i] == enintvec[i])
print(solver.check())
print(solver.model())
masterkey = solver.model()[masterkey].as_long()
ROUNDKEYS = keySchedule(masterkey)
print(decrypt(b'\xe6\xf9\xda\xf0\xe18\xbc\xb4[\xfb\xbe\xd1\xfe\xa2\t\x8d\xdft:\xee\x1f\x1d\xe2q\xe5\x92/$#DL\x00\x1dD5@\x01W?!7CQ\xc16V\xb0\x14q)\xaa2'))

你可能感兴趣的:(HGAME 2020 Week3&Week4 wp)