System Hacking - Linux Mitigation

1. checksec을 통한 확인

리눅스에서는 바이너리에 대해 다양한 보호기법을 가지고 있다. 이러한 보호기법은 checksec이라는 프로그램을 통해 확인할 수 있는데 아래와 같이 직접 설치하거나, pwntools를 설치하면 함께 설치되어 사용할 수 있다.

sudo apt install checksec
ubuntu@instance-20250406-1126:~/dreamhack/level1/cherry$ checksec chall
[!] Could not populate PLT: Cannot allocate 1GB memory to run Unicorn Engine
[*] '/home/ubuntu/dreamhack/level1/cherry/chall'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        No PIE (0x400000)
    SHSTK:      Enabled
    IBT:        Enabled
    Stripped:   No

그러면 각각이 나타내는 보호기법이 어떤 것들인지 알아보자.

2. RELRO (Relocation Read-Only)

GOT 등의 일부 메모리 영역을 읽기 전용으로 바꾸어서 GOT overwrite 공격을 방지하는 기법이다.

  • No RELRO: read-only 속성이 아예 부여가 되지않은 상태이다. got overwrite 공격이 가능하다.
  • Partial RELRO: .ctors(.init_array), .dtors(.fini_array), .jcr, .dynamic 영역이 read-only로 설정되고, .got.plt, .data, .bss 영역은 write가능하다. 따라서 got overwrite 공격이 가능하다.
  • Full RELRO: .data, .bss 영역을 제외하고 모든 영역이 read-only로 설정되어 got overwrite 공격이 불가능하다.

3. Stack Canary

Stack Canarybof 공격으로부터 보호하는 기법으로, 함수 시작 시에 스택에 canary라는 무작위 값을 배치하고, 함수가 종료될 때 이 값이 변조되었는지를 검사한다. 만약 bof로 인해 변경되었음을 확인하면 프로그램을 강제로 종료한다.

  • No canary found: canary가 없음
  • Canary found: canary가 있음

4. NX (No-eXecute bit)

NX는 메모리의 실행 권한을 제어하는 기능으로, 스택과 같은 데이터 영역에서 코드를 실행하지 못하도록 한다. 예를 들어 스택에서 NX가 없다면 바로 쉘코드를 올려서 실행할 수 있다.

  • NX enabled: NX가 켜져있음
  • NX disabled: NX가 꺼져있음

5. PIE (Position Independent Executable)

실행 시에 항상 다른 주소에 프로그램이 로드되도록 하여 코드의 절대 주소를 예측하기 어렵게 한다. 만약 No PIE로 설정되면 프로그램의 주소는 항상 고정된 위치에 로드되어 공격자는 ROP 공격 등을 쉽게 수행할 수 있다.

ASLR (Address Space Layout Randomization)과 함께 사용되는데, PIE는 데이터 영역 (스택, 라이브러리, 힙)과 코드 영역 모두 랜덤한 주소로 로드하는 것이고, ASLR은 데이터 영역만 랜덤화한다.