Search code examples
pythonpython-3.xpython-2.7xor

unsupported operand type(s) for ^: 'bytes' and 'bytes' with XOR


I asked this question before it's closed as a duplicate I tried the duplicate link but nothing work.

the full code:

import requests
import base64
import urllib.parse
import operator




username = "badministrator"
password = "Password1"
URL = "http://url/login.php"
values = {'username' : username, 'password' : password}

def first_login(url_login, value):
    with requests.Session() as c:
        c.post(url_login, data = value)
        response = c.get(url_login, verify=False, allow_redirects=True)
        Cookie = [value for key,value in c.cookies.get_dict().items()]
        cookie, IV = Cookie
        return cookie, IV

def base64_decode():
    cookie, IV = first_login(URL, values)
    decode_cookie = base64.b64decode(urllib.parse.unquote_to_bytes(cookie))
    decode_IV = base64.b64decode(urllib.parse.unquote_to_bytes(IV))
    return decode_cookie, decode_IV

def xor_exp():
    decoded_cookie, decoded_IV = base64_decode()
    decoded_IV[0] = bytes(map(operator.xor, b'a', b'b', decoded_IV[0]))
    decoded_cookie[0] = b'a'
    return decoded_IV, decoded_cookie


print(xor_exp())

I can't iterate in bytes or xor three bites together


Solution

  • bytes are immutable, so if you want to change their contents, you either can construct a new bytes object (like you would do with strings or tuples) or create a bytearray. I'll show them both, below:

    def xor_exp():
        decoded_cookie, decoded_IV = base64_decode()
        decoded_IV = bytes([3 ^ decoded_IV[0]]) + decoded_IV[1:]
        decoded_cookie = b'a' + decoded_cookie[1:]
        return decoded_IV, decoded_cookie
    
    def xor_exp():
        decoded_cookie, decoded_IV = base64_decode()
        decoded_cookie = bytearray(decoded_cookie)
        decoded_IV = bytearray(decoded_IV)
        decoded_IV[0] = 3 ^ decoded_IV[0]
        decoded_cookie[:1] = b'a'
        return bytes(decoded_IV), bytes(decoded_cookie)
    

    Attempt 2:

    If you know the bytes objects will only contain a single character, I would simply call ord on them:

    decoded_IV[0] = ord(b'a') ^ ord(b'b') ^ decoded_IV[0]
    

    Which, given these specific values is equal to

    decoded_IV[0] = 3 ^ decoded_IV[0]
    

    Attempt 1:

    You can not directly xor bytes objects in Python, but you can xor int objects, and bytes implement Iterable[int], which means you can do:

    import operator
    
    ...
    
    decoded_IV[0] = bytes(map(operator.xor, b'a', b'b', decoded_IV[0]))
    

    This uses the standard library function operator.xor and the builtin function map.