Skip to content

Unsafe Padding Character Issue in the ”b85decode” Function #136932

@lighting9999

Description

@lighting9999

Bug report

Bug description:

The vulnerable_b85decode  function uses  ~  as a padding character when processing Base85 decoding (to pad the length of the encoded string to a multiple of 5). However,  ~  itself is a valid encoding character in the Base85 alphabet (not a dedicated padding character). This causes confusion between the padding logic and the parsing of valid data, thereby introducing security vulnerabilities.

POC code:

import base64
import struct

# Original vulnerable b85decode implementation
def vulnerable_b85decode(b):
    """Original vulnerable Base85 decoding implementation"""
    # Simplified Base85 alphabet
    _b85alphabet = (b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~")
    
    # Create decoding table
    _b85dec = [None] * 256
    for i, c in enumerate(_b85alphabet):
        _b85dec[c] = i
    
    # Add padding
    padding = (-len(b)) % 5
    b = b + b'~' * padding  # Using '~' for padding
    
    out = []
    packI = struct.Struct('!I').pack
    
    for i in range(0, len(b), 5):
        chunk = b[i:i + 5]
        acc = 0
        try:
            for c in chunk:
                acc = acc * 85 + _b85dec[c]
            out.append(packI(acc))
        except TypeError:
            for j, c in enumerate(chunk):
                if _b85dec[c] is None:
                    raise ValueError(f'Invalid character {chr(c)} at position {i+j}')
            raise
        except struct.error:
            raise ValueError(f'Base85 overflow at block starting position {i}')
    
    result = b''.join(out)
    if padding:
        result = result[:-padding]
    return result

# Attack demonstration
def demonstrate_attack():
    print("Base85 Padding Character Attack Demonstration\n" + "="*40)
    
    # 1. Basic tampering attack
    print("\n1. Basic Tampering Attack:")
    original = b"Hello"
    encoded = b'NM&qnZB'
    decoded = vulnerable_b85decode(encoded)
    print(f"Original decoding: {decoded}")  # Should output b'Hello'
    
    # Attacker tampers with the encoded string
    malicious = encoded + b'~~~'  # Add three tildes
    malicious_decoded = vulnerable_b85decode(malicious)
    print(f"Tampered decoding: {malicious_decoded}")  # Outputs b'Hello\xd7\xa3\xf8'
    
    # 2. Data injection attack
    print("\n2. Data Injection Attack:")
    # Create malicious payload "EVIL"
    evil_payload = b'@<)q~'  # Should decode to b'EVIL'
    
    # Append to original encoding
    injected = encoded + evil_payload
    injected_decoded = vulnerable_b85decode(injected)
    print(f"Injected decoding: {injected_decoded}")  # Outputs b'HelloEVIL'
    
    # 3. Boundary condition attack
    print("\n3. Boundary Condition Attack:")
    # Create input that requires padding
    boundary = b'@<)q'  # Length 4, needs 1 '~' padding
    boundary_decoded = vulnerable_b85decode(boundary)
    print(f"Boundary input decoding: {boundary_decoded}")  # Should output b'EVL'
    
    # Now using malicious padding
    malicious_boundary = b'@<)q' + b'~'  # Explicitly add padding character
    malicious_boundary_decoded = vulnerable_b85decode(malicious_boundary)
    print(f"Malicious boundary input decoding: {malicious_boundary_decoded}")  # Outputs b'EVL' but is actually tampered
    
    # 4. Denial of Service attack
    print("\n4. Denial of Service Attack:")
    try:
        # Create input for an extremely large integer (5 '~'s = 84^5)
        dos_attack = b'~~~~~'
        vulnerable_b85decode(dos_attack)
    except Exception as e:
        print(f"DoS attack successful: {str(e)}")

if __name__ == "__main__":
    demonstrate_attack()

CPython versions tested on:

3.14

Operating systems tested on:

Windows

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy