인프런 커뮤니티 질문&답변

bioloidgp님의 프로필 이미지

작성한 질문수

리눅스 커널 해킹. A부터 Z까지

Kernel KPTI 적용시 영향?

해결된 질문

작성

·

503

·

수정됨

0

 

/mnt/c/Users/msh/Desktop/stack_based_BOF 1m 26s
❯ grep ": mov rdi, rax ; rep" ./gadgets.txt
0xffffffff8145a958 : mov rdi, rax ; rep movsb byte ptr [rdi], byte ptr [rsi] ; jmp 0xffffffff8145a368
0xffffffff814747df : mov rdi, rax ; rep movsb byte ptr [rdi], byte ptr [rsi] ; jmp 0xffffffff81474961
0xffffffff81479c79 : mov rdi, rax ; rep movsb byte ptr [rdi], byte ptr [rsi] ; jmp 0xffffffff81479cd8
0xffffffff8150a792 : mov rdi, rax ; rep movsb byte ptr [rdi], byte ptr [rsi] ; jmp 0xffffffff8150a391
0xffffffff81b08ab4 : mov rdi, rax ; rep movsb byte ptr [rdi], byte ptr [rsi] ; jmp 0xffffffff81b08a75
0xffffffff82a213e5 : mov rdi, rax ; rep movsb byte ptr [rdi], byte ptr [rsi] ; jmp 0xffffffff82a212b9
0xffffffff82a48d7c : mov rdi, rax ; rep movsb byte ptr [rdi], byte ptr [rsi] ; jmp 0xffffffff82a48d92
0xffffffff81b098e6 : mov rdi, rax ; rep movsb byte ptr [rdi], byte ptr [rsi] ; pop rbx ; pop rbp ; ret
0xffffffff82a081f0 : mov rdi, rax ; rep movsd dword ptr [rdi], dword ptr [rsi] ; ret
0xffffffff81132ad8 : mov rdi, rax ; rep movsq qword ptr [rdi], qword ptr [rsi] ; jmp 0xffffffff81132970
0xffffffff81b2413b : mov rdi, rax ; rep movsq qword ptr [rdi], qword ptr [rsi] ; ret
gef➤  x/10xi 0xffffffff82a081f0
   0xffffffff82a081f0:  Cannot access memory at address 0xffffffff82a081f0
gef➤  x/10xi 0xffffffff81132ad8
   0xffffffff81132ad8:  mov    rdi,rax
   0xffffffff81132adb:  rep movs QWORD PTR es:[rdi],QWORD PTR ds:[rsi]
   0xffffffff81132ade:  jmp    0xffffffff81132970
   0xffffffff81132ae3:  call   0xffffffff81b26270
   0xffffffff81132ae8:  nop    DWORD PTR [rax+rax*1+0x0]
   0xffffffff81132af0:  push   r15
   0xffffffff81132af2:  push   r14
   0xffffffff81132af4:  push   r13
   0xffffffff81132af6:  mov    r13,rdi
   0xffffffff81132af9:  push   r12

KPTI가 적용된 커널에서 일부는 주소를 찾아도 gdb로 확인을 할 수 없는데, 왜 그런건가요?

user level에서 page table이 줄어들어서 특정 부분이 빠지다보니, 그 가젯이 있는 부분도 빠져서 안보이는거 같은데, 약간 이상한거같습니다.

[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0xffffffff81b2c390
$rbx   : 0x0
$rcx   : 0x0
$rdx   : 0x22a
$rsp   : 0xffffffff82403eb0
$rbp   : 0x0
$rsi   : 0x83
$rdi   : 0x0
$rip   : 0xffffffff81b2c3ae
$r8    : 0xffff88801f01dec0
$r9    : 0x200
$r10   : 0x0
$r11   : 0x2f7
$r12   : 0x0
$r13   : 0x0
$r14   : 0x0
$r15   : 0x0
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x10 $ss: 0x18 $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00
───────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
[!] Unmapped address: '0xffffffff82403eb0'
─────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0xffffffff81b2c3a5                  verw   WORD PTR [rip+0x4d94d6]        # 0xffffffff82005882
   0xffffffff81b2c3ac                  sti
   0xffffffff81b2c3ad                  hlt
 → 0xffffffff81b2c3ae                  mov    ebp, DWORD PTR gs:[rip+0x7e4e4fab]        # 0x11360
   0xffffffff81b2c3b5                  nop    DWORD PTR [rax+rax*1+0x0]
   0xffffffff81b2c3ba                  pop    rbx
   0xffffffff81b2c3bb                  pop    rbp
   0xffffffff81b2c3bc                  pop    r12
   0xffffffff81b2c3be                  ret
─────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, stopped 0xffffffff81b2c3ae in ?? (), reason: SIGINT
───────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0xffffffff81b2c3ae → mov ebp, DWORD PTR gs:[rip+0x7e4e4fab]        # 0x11360
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  x/10xi 0xffffffff82a081f0
   0xffffffff82a081f0:  Cannot access memory at address 0xffffffff82a081f0

혹시 몰라서 qemu script에서 qemu64로 바꿔서 kpti를 끄고 gdb를 달아서 테스트를 해봤더니, 이상하게 나오네요.

$r12   : 0x0
$r13   : 0x0
$r14   : 0x0
$r15   : 0x0
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x10 $ss: 0x18 $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00
───────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
[!] Unmapped address: '0xffffffff82403eb0'
─────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0xffffffff81b2c3a5                  verw   WORD PTR [rip+0x4d94d6]        # 0xffffffff82005882
   0xffffffff81b2c3ac                  sti
   0xffffffff81b2c3ad                  hlt
 → 0xffffffff81b2c3ae                  mov    ebp, DWORD PTR gs:[rip+0x7e4e4fab]        # 0x11360
   0xffffffff81b2c3b5                  data16 data16 data16 xchg ax, ax
   0xffffffff81b2c3ba                  pop    rbx
   0xffffffff81b2c3bb                  pop    rbp
   0xffffffff81b2c3bc                  pop    r12
   0xffffffff81b2c3be                  ret
─────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, stopped 0xffffffff81b2c3ae in ?? (), reason: SIGINT
───────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0xffffffff81b2c3ae → mov ebp, DWORD PTR gs:[rip+0x7e4e4fab]        # 0x11360
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  x/10xi 0xffffffff82a081f0
   0xffffffff82a081f0:  int3
   0xffffffff82a081f1:  int3
   0xffffffff82a081f2:  int3
   0xffffffff82a081f3:  int3
   0xffffffff82a081f4:  int3
   0xffffffff82a081f5:  int3
   0xffffffff82a081f6:  int3
   0xffffffff82a081f7:  int3
   0xffffffff82a081f8:  int3
   0xffffffff82a081f9:  int3
gef➤

vmlinux를 잘못 추출한건가 싶어서 다시 추출해봤는데도 이상합니다.

답변 1

1

김현우님의 프로필 이미지
김현우
지식공유자

안녕하세요.

리눅스 커널 이미지는 런타임에서 command-line parameter 등에 의해 그 구조가 바뀔 수 있습니다.

KPTI를 적용하고 부팅한 커널에선, 커널 모드와 유저 모드로 전환하는 함수들의 흐름이 바뀌기도 하구요.

이런 경우엔 그냥 살아있는 가젯을 사용하거나, gdb의 find 명령어로 런타임에서 가젯을 찾는 것이 가장 간편한 방법입니다.

bioloidgp님의 프로필 이미지
bioloidgp
질문자

감사합니다