rsp-∞

[DreamHack] Mitigation : Stack Canary - 카나리 생성 과정 본문

Write-ups/system

[DreamHack] Mitigation : Stack Canary - 카나리 생성 과정

portrait.kim 2024. 5. 18. 11:11

 

카나리는 프로세스가 시작될 때 그 값을 TLS 영역에 저장하는데, 조금 더 간단하게는 TLS 영역을 가리키는 fs가 있으므로 이 fs의 값을 알면 TLS 영역의 주소를 알 수 있다. fs는 레지스터이지만 호출을 위해서는 다른 레지스터와 다르게 syscall을 사용해야 한다. fs의 값을 설정할 때 호출되는 시스템 콜인 arch_prctl(int code, unsigned long addr)에 breakpoint를 걸어 fs에 어떤 값이 할당되는지 알 수 있다.

 

이전 canary.c 동적 실습에서 다루었던 파일을 똑같이 gdb -q ./canary로 실행시키고, gdb에서 특정한 이벤트가 발생했을 때 실행을 멈추는 catch 명령어를 사용한다. 

 

pwndbg> catch syscall arch_prctl
Catchpoint 1 (syscall 'arch_prctl' [158])

 

이렇게 하면 fs의 값을 설정하는 코드의 바로 앞에 일종의 breakpoint를 걸어 주었다고 볼 수 있다. catchpoint가 실행될 때까지 프로세스를 continue한다.

 

pwndbg> c
Continuing.
Catchpoint 1 (call to syscall arch_prctl), init_tls (naudit=naudit@entry=0) at ./elf/rtld.c:818
818	./elf/rtld.c: No such file or directory.

 

 

─[ REGISTERS / show-flags off / show-compact-regs off ]─

*RAX  0xffffffffffffffda
*RBX  0x7fffffffdb90 ◂— 0x1
*RCX  0x7ffff7fe3dff (init_tls+239) ◂— test eax, eax
*RDX  0xffff800008056eb0
*RDI  0x1002
*RSI  0x7ffff7fa8740 ◂— 0x7ffff7fa8740

 

레지스터 영역의 일부를 보면 RDI가 0x1002임을 알 수 있다. 이 값은 ATCH_SET_FS의 상숫값이다. RSI의 값이 위와 같으므로 TLS는 이곳에 저장될 것이며, 곧 fs는 RSI의 값을 가리키게 될 것이라고 볼 수 있다. 카나리가 저장될 공간 fs+0x28은 그러므로 0x7ffff7fa8740+0x28이다. 이 공간에 값을 입력할 때 프로세스를 중단시키려면 watch 명령어를 사용할 수 있다. watch 명령어는 특정 주소의 값이 변경될 때 프로세스를 중단시킨다. 

 

pwndbg> watch *(0x7ffff7fa8740+0x28)
Hardware watchpoint 2: *(0x7ffff7fa8740+0x28)

 

이렇게 watchpoint를 설정하고 프로세스를 continue한다.

 

pwndbg> x/gx 0x7ffff7fa8740+0x28
0x7ffff7fa8768:	0x7824f0a99606d200

 

TLS 영역의 값, 카나리가 새롭게 설정된 것을 볼 수 있다. 역시나 00인 null값으로 시작한다.

'Write-ups > system' 카테고리의 다른 글

[DreamHack] Return to Library  (0) 2024.05.25
[DreamHack] ssp_001  (0) 2024.05.18
[DreamHack] Mitigation : Stack Canary - canary.c 실습 동적 분석  (0) 2024.05.18
[Bomb Lab] Phase_4  (0) 2024.05.12
[DreamHack] shell_basic  (0) 2024.05.12