Exemplo n.º 1
0
def decrypt_html(pms2, tlsn_session):
    '''Receive correct server mac key and then decrypt server response (html),
    (includes authentication of response). Submit resulting html for browser
    for display (optionally render by stripping http headers).'''
    print("\nStarting decryption of content, may take a few seconds...")
    try:
        tlsn_session.auditor_secret = pms2[:tlsn_session.n_auditor_entropy]
        tlsn_session.set_auditor_secret()
        tlsn_session.set_master_secret_half(
        )  #without arguments sets the whole MS
        tlsn_session.do_key_expansion(
        )  #also resets encryption connection state
    except shared.TLSNSSLError:
        shared.ssl_dump(tlsn_session)
        raise
        #either using slowAES or a RC4 ciphersuite
    try:
        plaintext, bad_mac = tlsn_session.process_server_app_data_records()


#        print(plaintext)
    except shared.TLSNSSLError:
        shared.ssl_dump(tlsn_session)
        raise
    if bad_mac:
        return False, "ERROR! Audit not valid! Plaintext is not authenticated."

    # if http data chunked, dechunk
    plaintext = shared.dechunk_http(plaintext)
    if global_use_gzip:
        plaintext = shared.gunzip_http(plaintext)
    return True, plaintext
Exemplo n.º 2
0
def prepare_pms(tlsn_session, session_id):
    n = shared.bi2ba(tlsn_session.server_modulus)
    rs_choice = random.choice(shared.reliable_sites.keys())
    print("ramdom choice:", rs_choice)
    for i in range(10):  #keep trying until reliable site check succeeds
        try:
            pms_session = shared.TLSNClientSession(
                rs_choice,
                shared.reliable_sites[rs_choice][0],
                ccs=53,
                tlsver=global_tlsver)
            if not pms_session:
                raise Exception(
                    "Client session construction failed in prepare_pms")
            tls_sock = shared.create_sock(pms_session.server_name,
                                          pms_session.ssl_port)
            pms_session.start_handshake(tls_sock)
            # 1# message exchange with auditor
            reply = send_and_recv(
                'rcr_rsr_rsname_n', pms_session.client_random +
                pms_session.server_random + rs_choice[:5] + n, session_id)
            if reply[0] != 'success':
                raise Exception(
                    'Failed to receive a reply for rcr_rsr_rsname_n:')
            if not reply[1] == 'rrsapms_rhmac_rsapms':
                raise Exception('bad reply. Expected rrsapms_rhmac_rsapms:')
            reply_data = reply[2]
            rrsapms2 = reply_data[:256]
            pms_session.p_auditor = reply_data[256:304]
            rsapms2 = reply_data[304:]
            response = pms_session.complete_handshake(tls_sock, rrsapms2)
            tls_sock.close()
            if not response:
                print("PMS trial failed")
                continue
            #judge success/fail based on whether a properly encoded
            #Change Cipher Spec record is returned by the server (we could
            #also check the server finished, but it isn't necessary)
            if not response.count(
                    shared.TLSRecord(shared.chcis,
                                     f='\x01',
                                     tlsver=global_tlsver).serialized):
                print("PMS trial failed, retrying. (",
                      binascii.hexlify(response), ")")
                continue
            tlsn_session.auditee_secret = pms_session.auditee_secret
            tlsn_session.auditee_padding_secret = pms_session.auditee_padding_secret
            tlsn_session.enc_second_half_pms = shared.ba2int(rsapms2)
            tlsn_session.set_enc_first_half_pms()
            tlsn_session.set_encrypted_pms()
            return
        except shared.TLSNSSLError:
            shared.ssl_dump(pms_session, fn='preparepms_ssldump')
            shared.ssl_dump(tlsn_session)
            raise
    raise Exception ('Could not prepare PMS with ', rs_choice, ' after 10 tries. Please '+\
                     'double check that you are using a valid public key modulus for this site; '+\
                     'it may have expired.')
Exemplo n.º 3
0
def make_tlsn_request(headers, tlsn_session, tls_sock):
    '''Send TLS request including http headers and receive server response.'''
    try:
        tlsn_session.build_request(tls_sock, headers)
        response = shared.recv_socket(
            tls_sock)  #not handshake flag means we wait on timeout
        if not response:
            raise Exception(
                "Received no response to request, cannot continue audit.")
        tlsn_session.store_server_app_data_records(response)
    except shared.TLSNSSLError:
        shared.ssl_dump(tlsn_session)
        raise

    tls_sock.close()
    #we return the full record set, not only the response to our request
    return tlsn_session.unexpected_server_app_data_raw + response
Exemplo n.º 4
0
def start_generate(server_name, headers, server_modulus):
    global global_tlsver
    global global_use_gzip
    global global_use_slowaes

    print("server_name:", server_name)
    session_id = ''.join(
        random.choice(string.ascii_lowercase + string.digits)
        for x in range(10))
    tlsn_session = shared.TLSNClientSession(server_name, tlsver=global_tlsver)
    tlsn_session.server_modulus = shared.ba2int(server_modulus)
    tlsn_session.server_mod_length = shared.bi2ba(len(server_modulus))

    print('Preparing encrypted pre-master secret')
    prepare_pms(tlsn_session, session_id)

    for i in range(10):
        try:
            print('Performing handshake with server')
            tls_sock = shared.create_sock(tlsn_session.server_name,
                                          tlsn_session.ssl_port)
            tlsn_session.start_handshake(tls_sock)
            retval = negotiate_crippled_secrets(tlsn_session, tls_sock,
                                                session_id)
            if not retval == 'success':
                raise shared.TLSNSSLError('Failed to negotiate secrets: ' +
                                          retval)
            print('Getting data from server')
            #
            response = make_tlsn_request(headers, tlsn_session, tls_sock)
            #prefix response with number of to-be-ignored records,
            #note: more than 256 unexpected records will cause a failure of audit. Just as well!
            response = shared.bi2ba(
                tlsn_session.unexpected_server_app_data_count,
                fixed=1) + response
            break
        except shared.TLSNSSLError:
            shared.ssl_dump(tlsn_session)
            raise
        except Exception as e:
            print(
                'Exception caught while getting data from server, retrying...',
                e)
            if i == 9:
                raise Exception('Notarization failed')
            continue

    # commit its own hash, get auditor's secrets
    ok, commit_hash, pms2, signature, audit_time = commit_session(
        tlsn_session, response, session_id)
    if not ok:
        return ok, "commit hash to auditor failed"
# no need to verify signatures
    msg = sha256(commit_hash + pms2 +
                 shared.bi2ba(tlsn_session.server_modulus) +
                 audit_time).digest()
    oracle_ba_modulus = binascii.unhexlify(oracle_modulus)
    oracle_int_modulus = shared.ba2int(oracle_ba_modulus)
    print(msg)
    print(signature)
    if not shared.verify_signature(msg, signature, oracle_int_modulus):
        raise Exception("Notarization FAILED, notary signature invalid.")

    ok, result = decrypt_html(pms2, tlsn_session)
    if not ok:
        return ok, result
    html = result

    print('Verified OK')

    host_line = "host: " + server_name + "\r\n"
    readable = host_line
    b = """""" ""

    b = """<meta[ ]+http-equiv=["']?content-type["']?[ ]+content=["']?text/html;[ ]*charset=([0-9-a-zA-Z]+)["']?"""
    B = re.compile(b, re.IGNORECASE)
    encodings = B.search(html)
    #    print("encoding:")
    if encodings != None:
        encoding = encodings.group(1)
        if encoding.lower() == 'gb231' or encoding.lower() == 'gb2312':
            html = html.decode('gb18030')
            #        print(html)
        else:
            html = html.decode(encoding)
    else:
        html.decode('utf-8')

    print("html len:", len(html))
    html = "response:\r\n" + html + '\r\n-----PROOF BINARY DATA-----\r\n'
    #    print(html)
    #    readable += html.decode().encode('utf-8')
    readable += html
    # chosen_cipher_suite
    audit_data = shared.bi2ba(tlsn_session.chosen_cipher_suite,
                              fixed=2)  # 2 bytes
    # client_random, server_random
    audit_data += tlsn_session.client_random + tlsn_session.server_random  # 64 bytes
    # pre_master_key, two parts, each generated by auditee or auditor
    audit_data += tlsn_session.pms1 + pms2  #48 bytes
    # length of server_cert, sent by TLS Server, why fix 3 ?
    audit_data += shared.bi2ba(len(tlsn_session.server_certificate.certs),
                               fixed=3)
    # server_certs, it's very hard to verify these babies on-chain.
    audit_data += tlsn_session.server_certificate.certs
    # tls version
    audit_data += tlsn_session.tlsver  #2 bytes
    # proposed tls version in ClientHello?
    #    audit_data += tlsn_session.initial_tlsver #2 bytes
    # length of response
    audit_data += shared.bi2ba(len(response), fixed=8)  #8 bytes
    # response data
    audit_data += response  #note that it includes unexpected pre-request app data, 10s of kB
    # IV_after_finished used by RC4, necessory to authenticate response
    IV = tlsn_session.IV_after_finished if tlsn_session.chosen_cipher_suite in [47,53] \
                else shared.rc4_state_to_bytearray(tlsn_session.IV_after_finished)
    # length of IV, should be before IV ?
    audit_data += shared.bi2ba(len(IV), fixed=2)  #2 bytes
    # IV
    audit_data += IV  #16 bytes or 258 bytes for RC4.
    # length of auditor's public key, in modulus formate
    audit_data += shared.bi2ba(len(oracle_ba_modulus), fixed=2)
    # auditor's signature
    audit_data += signature  #512 bytes RSA PKCS 1 v1.5 padding
    # hash that auditee commits to auditor
    audit_data += commit_hash  #32 bytes sha256 hash
    # auditor's public key
    audit_data += oracle_ba_modulus
    # timestamp used to make signature unique
    audit_data += audit_time
    #    audit_data = bytearray(readable.encode('utf-8')) + audit_data

    date = time_str = time.strftime('%d-%b-%Y-%H-%M-%S-', time.gmtime())
    filename = date + session_id + ".pgsg"
    #    print("proof file name:",filename)
    proofpath = join(PROOF_DIR, filename)
    with open(proofpath, "w") as f:
        f.write(readable)
        f.write(audit_data)

    return True, filename