regular

System Hacking - Pwnable

oose. 2023. 11. 21. 19:49

1. 포너블 개념

-포너블 : 공격을 위해 관리자 권한을 강탈해오는 것! -> shell을 탈취해야 함(shell = 사용자와 커널을 연결해주는 매개체) -> shell을 통해 공격 가능 

 

2. 레지스터

-레지스터 : CPU에서 요청을 처리하는 데 필요한 데이터를 일시적으로 저장하는 기억장치. CPU 옆에 붙어있고 CPU는 연산을 할 때 레지스터를 반드시 거쳐감

-x86 vs x64 : 한번에 처리할 수 있는 bit 수 -> 메모리 인식률, 레지스터에 적용시키면 x86-저장 가능한 공간 크기가 4기가

세션 ppt 자료(x64 ver)

 

https://ajy1120.tistory.com/10(x84 ver)

 

 

 

3. 리눅스 메모리 구조(유저 영역 - 프로세스 메모리 구조)

-스택 : 함수, 지역변수 정보 포함 -> 취약점 존재, 버퍼오버플로우 많이 발생, @주의@ 스택은 높은 주소에서 낮은 주소로 쌓임! 거꾸로 쌓인다고 보면 됨.

-heap : 동적 할당 malloc()

-bss : 변수들이 실제 위치하는 곳(초기화되지 않은 상태)

-data : 초기화된 변수가 위치하는 곳

-text(code) : 실제 우리가 작성한 소스 코드가 들어가있는 공간

 

 

4. cdecl

-stack frame : 스택 영역에 차례대로 저장되는 함수의 호출 정보 -> 스택 프레임 덕분에 함수의 모든 호출이 끝난 뒤, 해당 함수가 호출되기 이전 상태로 돌아갈 수 있음. 

  x86(32bit) x64(64bit)
함수 호출 규약 cdecl sysv

 

-cdecl : x86에서 사용되는 함수 호출 규약, c에서도 기본적으로 사용됨. 

int sum(int a, int b) {
  return a + b;
}

void main(void) {
  sum(1,2);
}

 

- 위 코드에서 sum 함수를 부르는 main 함수가 caller, 호출 당하는 sum 함수는 callee

- 인자는 

- 인자 전달 방법 : stack을 통해 전달(오른쪽 -> 왼쪽 ), 리턴 값은 eax를 통해 전달 받음. 인자 정리는 callee가 아닌 caller가 함.

- 처리 순서 

  1. caller가 전달할 argument를 stack에 push
  2. callee prolog
  3. callee epilog
  4. caller가 call과정에서 사용한 stack 정리

-push할 때마다 esp 4씩 증가

 

 

 

5. sysv

-sysv : x64에서 사용되는 함수 호출 규약

  1. 6개의 인자를 RDI, RSI, RDX, RCX, R8, R9에 순서대로 저장하여 전달.
    더 많은 인자를 사용해야 할 때는 스택을 추가로 이용
  2. callee prolog
  3. callee epilog
  4. caller가 call과정에서 사용한 stack 정리
  5. 함수의 반환 값은 RAX로 전달

 

 

 

 

6. Stack frame 변화 과정

-stack frame : 어떤 함수가 실행될 때, 스택 안에서 그 함수의 영역을 구분하기 위해 생성되는 공간, 함수 프롤로그(Prolog)와 에필로그(Epilog)를 수행하여 영역 표현을 함.

-함수 프롤로그(Prolog) : push %ebp, mov %ebp, %esp -> ebp를 스택에 저장한 후, esp를 ebp에 복사함. ebp를 기준으로 함수 위치 정보를 파악할 수 있음

-함수 에필로그(Epilog) : leave, ret 

 1) leave : move esp, ebp, pop ebp로 나눠짐

 2) ret : pop eip, jmp eip로 나눠짐

 

 

[gate@localhost /tmp]$ gdb -q stack
(gdb) set dis int
(gdb) disas main
Dump of assembler code for function main:
0x80483e8 <main>:       push   ebp
0x80483e9 <main+1>:     mov    ebp,esp
0x80483eb <main+3>:     sub    esp,20
0x80483ee <main+6>:     push   0x804846f
0x80483f3 <main+11>:    call   0x8048308 <printf>
0x80483f8 <main+16>:    add    esp,4
0x80483fb <main+19>:    call   0x80483d0 <func>
0x8048400 <main+24>:    xor    eax,eax
0x8048402 <main+26>:    jmp    0x8048404 <main+28>
0x8048404 <main+28>:    leave
0x8048405 <main+29>:    ret
End of assembler dump.

 

위 코드에서 

 

 

프롤로그

에필로그

 

 

 

-함수 호출 call fun 

<프롤로그>

push rip, jmp fcn -> 스택에 다음 함수 실행 위치가 저장됨 (push rip), 

move rbp, rsp -> rbp에 rsp값 저장

sub rsp -> callee의 각종 지역 변수들이 쌓임

 

<에필로그>

move rsp, rbp -> rbp값이 rsp에 저장

pop rbp