
COBOL 레거시 시스템을 위한 보안 강화 툴킷 — 보이지 않는 유니코드 탐지, 형식 경계 분석, 소스 변환 무결성
COBOL 레거시 시스템을 위한 보안 감사 툴킷
VTR Research Methodology의 일부 | DOI: 10.5281/zenodo.22063208 상태: 재현 가능 | 라이선스: MIT | 트랙: 핵심 인프라
GnuCOBOL 소스에서 컴파일 컨텍스트 분기, 보이지 않는 유니코드 공격, 안전하지 않은 COBOL 패턴을 탐지합니다. 동일한 소스 파일을 -fixed와 -free로 컴파일하면 서로 다른 프로그램이 생성됩니다 — 이 도구는 그 분기를 관찰 가능하고 재현 가능하게 만듭니다.
git clone https://github.com/LuisCastellanos-dev/cobol-shield
cd cobol-shield
bash tools/poc_compiler_flag.sh
이 도구는 원격 코드 실행, 권한 상승, 네트워크 익스플로잇을 주장하거나 입증하지 않습니다. 발견 사항은 VTR 방법론에 따라 CONFIRMADO, PROBABLE, OBSERVADO로 분류됩니다 — 분류는 영향의 심각도가 아니라 증거의 강도를 반영합니다.
COBOL 레거시 시스템을 위한 보안 감사 툴킷
GnuCOBOL 소스에서 보이지 않는 유니코드 공격, 안전하지 않은 COBOL 패턴, 형식 변환 무결성 문제를 탐지합니다. GnuCOBOL 3.1.2로 검증되었습니다. IBM Enterprise COBOL 또는 Micro Focus에서의 동작은 검증되지 않았습니다 — 컴파일러별 플래그 의미가 다를 수 있습니다.
PIC X는 모든 것을 받아들입니다. 여러분의 배치는 그러면 안 됩니다.
cobol-shield는 두 가지 서로 다른 위협 표면을 다룹니다:
1. 유니코드 보이지 않는 문자 — CVE-2021-42574 및 Glassworm 계열 벡터로, 시각적 코드 리뷰를 우회하고 PIC X 필드를 조용히 손상시킵니다.
2. COBOL 정적 분석 — 레거시 소스의 안전하지 않은 패턴: 초기화되지 않은 working-storage, 검사되지 않은 STRING/UNSTRING 오버플로, REDEFINES 크기 불일치, 그리고 변환 시 의미가 바뀌는 고정 형식 위치 조건.
| 파일 | 목적 |
|---|---|
tools/check-invisibles.py | CI 검사기 — 보이지 않는 유니코드 탐지 시 종료 코드 1 |
tools/clean-invisibles.py | 포렌식 감사 로그를 갖춘 정제기 |
src/AUDITOR-INVISIBLE.cob | HEX-OF를 사용하는 COBOL 내 바이트 검증기 |
tools/cobol_rules.py | 정적 분석 규칙 R-01부터 R-04까지 |
tools/transform_renumber.py | 고정 형식 재번호 이동 시뮬레이터 (Phase 2) |
tools/poc_compiler_flag.sh | 결정적 PoC — 동일 파일, -fixed 대 -free, 컴파일러 플래그 분기 |
tools/poc_differential.sh | Phase 2 차분 PoC — SOURCE A 대 SOURCE B (수동 마이그레이션) |
각 규칙은 context_loader를 통해 cryptofault 및 vtr-forensic-img와 호환되는
VTR Finding Schema v1 출력을 생성합니다.
| 규칙 | 이름 | 심각도 | 분류 |
|---|---|---|---|
| R-01 | UNINITIALIZED_WS | 높음 | HECHO |
| R-02 | UNSTRING_NO_OVERFLOW | 높음 | HECHO |
| R-03 | REDEFINES_SIZE_MISMATCH | 높음 | HECHO |
| R-04 | FORMAT_BOUNDARY_ANALYSIS | 정보 | PROYECCION |
R-01 — UNINITIALIZED_WS VALUE 절 없이, 그리고 PROCEDURE DIVISION에서 INITIALIZE 또는 MOVE 없이 선언된 Working-Storage 변수를 탐지합니다. 배치 및 CICS 환경에서 조용한 정의되지 않은 동작 위험이 있습니다.
R-02 — UNSTRING_NO_OVERFLOW ON OVERFLOW 처리가 없는 STRING/UNSTRING 문을 탐지합니다. 입력이 대상 필드 길이를 초과할 때 조용한 잘림이 발생합니다.
R-03 — REDEFINES_SIZE_MISMATCH 재정의된 필드가 기본 필드보다 더 많은 바이트를 선언하는 REDEFINES를 탐지합니다. 메모리 경계 위반 위험 — 컴파일러 의존적 동작입니다.
R-04 — FORMAT_BOUNDARY_ANALYSIS (Phase 1 — 관찰만) 고정 형식 COBOL 소스의 위치 조건을 탐지합니다:
COL73_NONEMPTY — 식별 영역(73–80열)에 공백이 아닌 내용COL7_VERB — 주석 처리된 줄(7열 = * / / / D)에 COBOL 실행 가능 동사SOURCE_BOUNDARY — 80열을 초과하는 내용R-04는 severity=info, classification=PROYECCION을 생성합니다. 이는
형식 조건을 문서화하는 것이지 취약점이 아닙니다. 영향 평가에는 변환
차분 분석(Phase 2)이 필요합니다.
핵심 논지: COBOL 고정 형식 파일은 빌드에 사용된 컴파일러 플래그에 따라 다른 의미를 가지며 — 그 플래그는 소스 파일 외부에 존재합니다.
GnuCOBOL 3.1.2, 단일 아티팩트, 수정 없이 입증:
bash tools/poc_compiler_flag.sh
cobc -x -fixed poc-same-file.cbl → 컴파일됨 → 출력: 0000001000
cobc -x -free poc-same-file.cbl → 10개의 컴파일 오류
-fixed에서는: 6번째 줄 7열=*이 주석 표시자입니다 — MOVE 999999는
휴면 상태이고, 프로그램은 실행되어 1000을 표시합니다.
-free에서는: 시퀀스 번호 000100...001000이 숫자 리터럴로 파싱됩니다 —
PROGRAM-ID 헤더가 누락되었다고 보고되고, 모든 줄이 오류를 생성합니다.
동일한 파일이 구문적으로 유효하지 않게 됩니다.
컴파일러 플래그는 소스 파일 내부에 있지 않습니다. 그것은 Makefile, CI 구성, 또는 운영자 호출에 존재합니다. 이를 변경하는 것 — 의도적이든 실수든 — 은 프로그램이 유효한지 그리고 무엇을 하는지를 바꿉니다.
증거: corpus/fixed-format/poc-evidence.md
SHA-256 및 전체 오류 로그가 문서화되어 있습니다.
이전 PoC는 수동 마이그레이션을 통해 동일한 논지를 입증합니다:
SOURCE A (고정 형식, 7열='*' 휴면): 출력 → 0000001000
SOURCE B (자유 형식, 코드 활성): 출력 → 0000999999
SHA-256 A: b70a948a0df5e8f685e82f5bffc9c4710f2c0a7a23b6294e7ca20092c2d25d37
SHA-256 B: f5fd80f79ed3e5be97628f89790256d6fba80605dce2b7985b729b5fef6f26d5
한계: SOURCE B는 잘못된 마이그레이션의 수동 표현이며, 실제 재번호 매김 하의 IBM Z Open Editor 또는 IBM SCU의 출력이 아닙니다. 위의 컴파일러 플래그 PoC에는 이 한계가 없습니다.
탐지 범위:
| 코드포인트 | 이름 | 위험 |
|---|---|---|
| U+0001–U+001F | C0 제어 문자 | 배치 비정상 종료 |
| U+200B–U+200F | 제로 폭 문자 | 데이터 손상, VSAM 잘림 |
| U+202A–U+202E | 양방향 재정의 | 트로이 목마 소스 — CVE-2021-42574 |
| U+2066–U+2069 | 양방향 격리 | 방향 스푸핑 |
| U+FE00–U+FE0F | 변형 선택자 | Glassworm 계열 스테가노그래피 |
| U+E000–U+F8FF | 사용자 정의 영역 | 페이로드 은닉 |
| U+FEFF | BOM | 조용히 앞에 추가된 바이트 |
# 바이트 수준 검사
hexdump -C source.cob | grep -E "e2 80 (8b|ae)"
# 유니코드 CI 검사 — 탐지 시 종료 코드 1
python3 tools/check-invisibles.py .
# 포렌식 감사 로그로 정제
python3 tools/clean-invisibles.py . --report audit-$(date +%Y%m%d).log
# 정적 분석 규칙 실행
python3 -c "
from tools.cobol_rules import scan_path_r01, scan_path_r02, scan_path_r03, scan_path_r04
import json
for f in scan_path_r02('your-source.cbl'):
print(f.to_json())
"
# 변환 차분 PoC
bash tools/poc_differential.sh
- name: Check for invisible Unicode
run: python3 tools/check-invisibles.py .
PIC X(n)은 원시 바이트 버퍼입니다. 검증 없이 어떤 바이트 시퀀스든
받아들입니다. Zowe API 계층이 MOVE를 통해 JSON을 COBOL 카피북으로
전달할 때, 보이지 않는 유니코드가 조용히 레코드에 들어갑니다.
고정 형식 COBOL은 두 번째 표면을 추가합니다: 위치 열 의미론 (7열은 표시자 영역, 73–80열은 식별 영역)은 형식에 의존합니다. 이러한 의미론을 보존하지 않는 마이그레이션 도구는 휴면 코드를 활성화하거나 프로그램 구조를 조용히 손상시킬 수 있습니다.
CVE-2021-42574와 공유하는 메커니즘은 탐지 격차입니다 — 시각적 검사를 우회하는 내용. 데이터 필드 잘림 벡터와 형식 변환 벡터는 CVE-2021-42574에 설명된 소스 코드 의미 반전과는 구별됩니다.
pip install pytest
python -m pytest tests/ -q
# 159 tests, 0 failures
컴파일러 범위: 모든 규칙은 GnuCOBOL 3.1.2에 대해서만 검증되었습니다. IBM Enterprise COBOL과 Micro Focus COBOL은 다른 플래그 의미, 열 경계 동작, 확장 지원을 가집니다. 해당 컴파일러에서의 결과는 검증되지 않았습니다 — 테스트될 때까지 INFERENCIA로 분류하십시오.
R-04 키워드 매칭 (COL7_VERB): 주석 처리된 줄에서 COBOL 동사 탐지는 고정 키워드 목록을 사용합니다. 목록에 없는 보안 관련 동사를 포함하는 주석 처리된 줄은 거짓 음성을 생성합니다. 이러한 이유로 R-04는 PROYECCION으로 분류됩니다 — 이는 조건을 문서화하는 것이지 확인된 취약점이 아닙니다.
cfg-shield 유사 — 기능 이름 의존성: METHODOLOGY.md에 문서화된 교차 언어 방법론은 기능/플래그 이름이 인식 가능한 관례를 따른다고 가정합니다. 설명적이지 않은 이름(예: legacy, compat)을 가진 보안 관련 플래그는 수동 검토 없이 올바르게 분류되지 않을 수 있습니다.
단일 컴파일러 PoC: 결정적 PoC(poc-same-file.cbl)는 GnuCOBOL에서의 분기를 입증합니다. 동일한 분기 클래스가 다른 COBOL 컴파일러에서도 예상되지만 아직 검증되지 않았습니다.
MIT