[시스템 해킹] 메모리 보호기법

·2024년 9월 27일

Security

목록 보기
9/60

NX bit

  • NX bit 가 걸려있다면, 스택에 실행권한이 존재하지 않는 것 → rwx 권한 중 x 권한 없는 것.
  • 실행 권한이 존재하지 않으면 Shellcode를 넣고 프로그램 흐름을 변조하더라도 shellcode 실행이 되지 않음 → Return to Shellcode 기법 사용 어려움
  • 다만 NX bit 걸려 있는 바이너리에서 shellcode를 실행시키려면 mprotect와 같은 함수를 불러 원하는 메모리 공간에 rwx 권한을 준 후 shellcode를 실행시키는 여러 chaining 과정이 필요함 → ROP 기법에서 다룸

ASLR

  • 힙, 스택, 라이브러리 영역의 base 주소를 바이너리를 실행할 때마다 Randomization 시켜 고정된 주소로 메모리에 직접 접근하는 행위를 할 수 없게끔 함
  • 스택 base 주소가 매번 바뀌니 shellcode가 들어간 스택 주소까지 알아내기 어렵게 됨
  • 각 메모리 영역의 base 주소만 Radomization 시키는 것이기 때문에 base 주소만 알아낸다면 해당 메모리 영역에서 원하는 주소에 base + offset 으로 맘대로 접근하는 게 가능해짐
  • 특정 영역에 해당하는 메모리 주소를 하나라도 가지고 있다면 offset을 빼서 base주소를 알아내는 게 가능해지고 알아낸 메모리 영역 내에서 원하는 공간에 마음대로 접근할 수 있게 됨.
  • 프로그램에 취약점이 존재해서 메모리에 존재하는 스택 주소나 라이브러리 주소를 그대로 화면에 출력할 수 있게 된다면 ASLR을 우회할 수 있게 됨 → memory leak (ROP 기법에서 다룸)

SSP

  • SSP(Stack Smashing Protector) 는 BOF가 터지더라도 exploit으로 연계되는 것을 방어하기 위해서 sfp 위에 랜덤한 값을 넣어서 함수 에필로그 과정에서 해당 값을 변조 여부를 체크하는 보호 기법
  • 랜덤한 값을 Canary라고 부름, sfp나 ret을 덮기 위해선 canary 값을 덮을 수 있어야 함
  • canary 값이 변조될 경우 __stack_chk_fail 함수를 호출하여 프로그램을 강제 종료 시키게 됨
    pwndbg> disass main
    Dump of assembler code for function main:
       0x00000000004006f7 <+0>:	push   rbp
       0x00000000004006f8 <+1>:	mov    rbp,rsp
       0x00000000004006fb <+4>:	sub    rsp,0x40
       **# fs:0x28을 참조해 Canary값을 가져와 rbp-0x8에 저장
       # rbp-0x8은 sfp 바로 이전 주소임**
       **0x00000000004006ff <+8>:	  mov    rax,QWORD PTR fs:0x28  
       0x0000000000400708 <+17>:	mov    QWORD PTR [rbp-0x8],rax**
       0x000000000040070c <+21>:	xor    eax,eax
    # rbp-0x8의 값과 fs:0x28의 값을 비교
       0x00000000004007d2 <+219>:	mov    rcx,QWORD PTR [rbp-0x8]
       0x00000000004007d6 <+223>:	xor    rcx,QWORD PTR fs:0x28
       0x00000000004007df <+232>:	je     0x4007e6 <main+239>
       0x00000000004007e1 <+234>:	call   0x4005c0 <__stack_chk_fail@plt>
       0x00000000004007e6 <+239>:	leave  
       0x00000000004007e7 <+240>:	ret    
    End of assembler dump.
  • memory leak을 내어 카나리값을 알아내거나 master canary(fs:0x28)을 원하는 값으로 덮거나 자식 프로세스를 사용할 때 1byte씩 brute force하여 카나리 값 알아낼 수 있음

RELRO

  • 프로세스의 섹션을 보호하는 기술
  • 3가지 모드가 있음
    • Full relro : data, bss를 제외한 모든 섹션에서 쓰기 권한을 없앰. → GOT Overwrite가 불가함
    • Pertial relro : GOT 섹션에 쓰기 권한이 존재함. → Lazy binding 과정을 거쳐서 함수 주소를 가져오고 GOT Overwrite 진행 가능
    • No relro : ELF 기본 헤더와 code영역을 제외하고는 거의 모든 섹션에 쓰기 권한 존재. .init, .fini와 같은 섹션 또한 덮어쓸 수 있음.

PIE

  • PIE (Position Independent Execution) ; 위치 독립 실행
  • binary base 주소를 Randomization 시킴. 동작 원리는 ASLR과 유사함
  • ASLR이 binary에 적용된 것과 유사. → PIE가 적용된 바이너리는 code, data, bss 등 섹션들의 주소를 알 수 없게 됨
  • binary base 자체가 계속 바뀌어 code 영역의 가젯(코드 조각)에 의존적인 ROP 공격을 어렵게 만드는 보호 기법 → memory leak 을 내는 게 확실한 방법

⇒ 프로그램이 실행 중에 있을 때 PIE base를 leak할 수 있다면, 이를 기반으로 함수들에 대한 offset을 구하여 exploit을 진행해주면 됨.

profile
Whatever I want | Interested in DFIR, Security, Infra, Cloud

0개의 댓글