glibc got overwrite
우리가 흔히 got overwrite를 통해 익스코드를 많이 짠다. 하지만,
C
[*] '/home/gaia/chall'
Arch: amd64-64-little
RELRO: FULL RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
SHSTK: Enabled
IBT: Enabled
Stripped: No다음과 같이 FULL RELRO로 보안이 강화되어 있으면 해당 방법이 불가능하다. 이럴때,
C
[*] '/home/gaia/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
SHSTK: Enabled
IBT: Enabledlibc도 한번 확인을 해보면 좋다. 만약 Partial RELRO 라면 glibc got overwrite 공격도 충분히 해볼만하다.
일단 기본적인 아이디어는 Arbitrary writable이 가능하다는 점과 glibc의 relocation 영역중 IFUNC의 relocation 영역을 노리는 것이다.
관련 분석글은 다음에 있다.
IFUNC들은 glibc 내부에서도 plt → got 영역을 거치기에 got를 overwrite 한뒤 main 코드에서 자연스럽게 IFUNC을 호출하게 하든가 ( ex, puts 내부에는 strlen이 사용됨 ) 아니면 control flow를 직접 바꿔줘야한다.
keyme님이 사용한 방식으로는 onegadget의 조건 rsi rdx null 을 만족시키기 위해서
iconv/gconv_conf.c 파일의
new_alias->fromname = memcpy ((char *) new_alias + sizeof (struct gconv_alias), from, wp - from);
C
pwndbg> x/10i 0x2CDC4
0x2cdc4: lea 0x10(%r8),%rdi
0x2cdc8: mov %rbx,%rsi
0x2cdcb: mov %r8,0x8(%rsp)
0x2cdd0: sub %rbx,%rbp
0x2cdd3: call 0x28620 <ABS+0xa9c90@plt>다음 부분을 사용하였고 memcpy 의 got를 덮어썼다.
이로써 공격방식이 엄청 다채로워질수 있는데 특히 내가 glibc 코드 중에서 IFUNC을 사용하는 거의 대부분의 코드를 일시적으로 사용할 수 있어진게 정말 좋은 것 같다.