```html HTML ``` Taylor Wessing 데이터 유출 도구 키트 - PhishDestroy
반검열 미러 및 보안 도구

📡 테일러 위싱 데이터 유출 툴킷

유니버설 포렌식 감사 및 레이어 분해 스위트 — Taylor Wessing LLP와 Valve Corporation의 시각적 전용 PDF 편집(레드액션)을 폭로하고 식별하기 위한 도구.

검열 저항성

이 툴킷과 관련 사례 연구는 여기에 영구적으로 미러링되어 있습니다. 법적 위협, DMCA 삭제 요청, 또는 테일러 웨싱 법률사무소(Taylor Wessing LLP) 또는 Valve Corporation 공개적이고 부인할 수 없는 증거로 간주될 것이며, 이는 보안 연구를 검열하려는 시도이자 기술적 무능력을 은폐하려는 행위로 취급될 것입니다.

Forensic PDF analysis
법의학 PDF 감사: 문서 드로잉 레이어를 재생성하고 검사하여 가짜 블랙박스 벡터 오버레이를 제거하고, 편집되지 않은 원본 텍스트를 추출합니다.

🔍 경영진 요약

The 유니버설 PDF 편집 감사기 및 레이어 분해기 는 전문적이고 오프라인 우선 방식의 포렌식 감사 및 레이어 분해 제품군으로, 시각적 전용 PDF 편집(Redaction) 취약점을 식별, 검증, 정화하도록 특별히 설계되었습니다. 이 툴킷은 보안 연구원, 데이터 보호 책임자, 규정 준수 감사관이 공개 공개 전에 문서 구조적 무결성을 검증할 수 있는 오픈소스 유틸리티 역할을 합니다.

⚖️ 기술적 권력 비대칭

이 감사 유틸리티는 기업 데이터 처리에서 발생하는 심각한 권력 불균형을 해소하기 위해 설계되었습니다. 거대한 대기업(예: Valve Corporation)는 정예 로펌(예: 테일러 웨싱 법률사무소(Taylor Wessing LLP)), 체계적인 데이터 노출은 기업이나 그들의 고액 연봉을 받는 변호사들에게는 타격을 주지 않지만, 그들의 고객들의 프라이버시를 치명적으로 훼손한다. 상대방 (법적·기술적 과실로 인해 민감한 개인정보가 유출된 개인 정보주체, 제3자 사용자, 미성년자). 이 툴킷은 개인과 독립 감사자가 데이터 안전성을 검증하고 기업 행위자에게 책임을 묻도록 지원한다.

📊 사례 연구: Taylor Wessing / Valve GDPR 유출

GDPR 제15조에 따른 Steam 사용자 데이터 관련 정보주체 접근 요청(SAR) 처리 과정에서, 외부 법률 자문이 처리 및 발송한 문서에서 중대한 보안 취약점이 확인되었습니다. 테일러 웨싱 법률사무소(Taylor Wessing LLP) 대신하여 Valve Corporation.

기술적 고장 분석

원시 문자 배열을 PDF 콘텐츠 스트림 내부에서 영구적으로 삭제하는 대신, 자동화된 맞춤형 PDF 생성 파이프라인(활용 Aspose.PDF for .NET)이 배포되었습니다. 이 시스템은 민감한 필드의 좌표를 프로그래밍 방식으로 쿼리하고 그렸습니다. 단색 검정 벡터 도형 (이하 PDF의 내용을 사용하여) ref/F/b/B 운영자)를 텍스트 위에 추가합니다.

시각적 드로잉 레이어는 그 아래의 원시 텍스트 배열을 변경하거나 파괴하지 않기 때문에, 계정 자격 증명, 로그인 정보, 이메일, 보안 로그, 미성년자 비식별화 해제 데이터를 포함한 수천 건의 비공개 기록이 완전히 온전한 상태로 유지되어, 전송된 파일에서 복사 및 추출이 가능했습니다.

📂 증거 자료 A: 패트릭 주르하이데 박사와의 유출된 서신

아래는 수신된 정확한 응답입니다. 패트릭 주어하이드 박사 (테일러 웨싱(Taylor Wessing LLP)의 샐러리 파트너)는 PhishDestroy가 해당 법무법인에 PDF 편집(redaction) 실패와 이에 따른 Steam 사용자 데이터 유출을 공식적으로 통보한 이후, GDPR 제33조에 따른 침해 통지 절차를 시작하는 대신 다음과 같은 내용을 작성하기로 선택했습니다:

안녕하세요, PhishDestroy 팀에게,

번역된 듯하지만 상당히 재미있는 메시지 감사합니다. PhishDestroy 팀에 보낸 "형사 처벌 관련" 커뮤니케이션이라는 것이 정확히 어떤 연락을 말씀하시는 건가요? 저는 PhishDestroy와 어떤 형태로든 이전에 소통한 적이 없다고 확신합니다. 따라서 해당 주장과 관련된 커뮤니케이션을 제공해 주시기 바랍니다. 그래야 무슨 내용인지 파악할 수 있을 것입니다.

귀하의 서신은 내용상 아쉽게도 이해하기 어렵거나 전혀 따라갈 수 없습니다. 참고로, 귀하의 서신 하단에 있는 것과 같은 면책 조항은, 실제 행위가 이와 상충할 경우 아무런 의미가 없습니다.

패트릭 주르하이데

🔍 PhishDestroy 분석:

  • 재미있는 메시지 고액을 받는 "IT 법률 전문가"가 미성년자들의 노출된 Steam 계정이 포함된 대규모 GDPR 데이터 유출에 대한 포렌식 통지를 "재미있다"고 평가했다.
  • 거의 또는 전혀 따라갈 수 없음 우리는 그에게 정확한 16진수 값, 그의 PDF 메타데이터, 36초 배치 파이프라인 타임스탬프, 그리고 해당 Aspose 20.8 누출을 초래한 버전. 보아하니, IT 법학 박사에게 IT 지표는 따라가기엔 너무 "어렵다"고 한다.

🛠️ 다중 도구 기능

이 스위트는 가짜 시각적 편집(레드랙션)을 분석하고 해체하기 위한 세 가지 상호 보완적인 완전 클라이언트 측 모드를 제공합니다:

  • 📡 모드 1: X-Ray 스캐너(PDF.js): 시각적 PDF 표시를 렌더링하지만, 실시간으로 그 아래에 있는 편집되지 않은 텍스트 문자를 추출합니다. 검은 상자는 보이지만, 비밀은 즉시 읽을 수 있습니다.
  • ✂️ 모드 2: 레이어 스트리퍼(PDF-Lib): 수술적 스트림 수준 정화. 직사각형 시각적 페인트 명령을 물리적으로 대체합니다.re f, re F)와 함께 n (no-paint) 연산자, 검은색 막대를 삭제합니다.
  • 🔎 모드 3: 충돌 감사 (Fitz 레이아웃): 겹치는 텍스트와 그래픽을 강조하여 유출 목록을 자동으로 생성합니다.

💻 CLI 사용법 (decensor.py)

# 1. Decompose PDF to raw text layers (Strips all drawings, lines, and masks globally)
python decensor.py -i compromised.pdf -d -o naked_document.pdf

# 2. Extract and save all text hidden under black visual shapes to a leaks text report
python decensor.py -i compromised.pdf -e verified_leaks.txt

# 3. List page-by-page structural element counts
python decensor.py -i compromised.pdf -l

🔍 핵심 Python 스트림 새니타이저

import re, fitz

def strip_black_bars_global(input_path, output_path):
    doc = fitz.open(input_path)
    for xref in range(1, doc.xref_length()):
        if not doc.is_stream(xref):
            continue
        try:
            obj_dict = doc.xref_object(xref)
            if any(m in obj_dict for m in ["/Type /Font", "/Subtype /Image", "/Type /Halftone"]):
                continue
                
            stream_bytes = doc.xref_stream(xref)
            text = stream_bytes.decode('latin-1')
            
            # Swap rectangular painting operators with no-fill 're n', preserving newlines
            modified_text, count = re.subn(
                r'\bre\s+([fFbB]\*?)(?=\s|$)',
                lambda m: f"re{m.group(0)[2:-len(m.group(1))]}n",
                text
            )
            if count > 0:
                doc.update_stream(xref, modified_text.encode('latin-1'))
        except Exception:
            continue
    doc.save(output_path, garbage=4, deflate=True, clean=True)
    doc.close()