728x90
반응형
이론
프로그램이 return 함수와 함께 종료되는 경우 main 함수는
__libc_start_main
__GI_exit
__run_exit_handlers
_dl_fini
등의 함수를 차례로 거치며 종료되는데,
이 중 _dl_fini 코드 내의 _rtld_global 구조체에서
_dl_load_lock을 인자로 __dl_rtld_lock_recursive 함수를 호출하게 된다.
# define __rtld_lock_lock_recursive(NAME) \
GL(dl_rtld_lock_recursive) (&(NAME).mutex)
void
_dl_fini (void)
{
#ifdef SHARED
int do_audit = 0;
again:
#endif
for (Lmid_t ns = GL(dl_nns) - 1; ns >= 0; --ns)
{
/* Protect against concurrent loads and unloads. */
__rtld_lock_lock_recursive (GL(dl_load_lock));
취약점
모든 보호 기법이 걸려 있더라도 임의의 주소에 값을 쓸 수 있다면, 상기 주소에 각각 /bin/sh 문자열, system 함수 주소를 삽입하여 셀 획득이 가능하다.
각각의 주소는 아래와 같이 구할 수 있다.
#peda
gdb-peda$ p &_rtld_global._dl_load_lock
$2 = (__rtld_lock_recursive_t *) 0x7ffff7ffd968 <_rtld_global+2312>
gdb-peda$ p &_rtld_global._dl_rtld_lock_recursive
$3 = (void (**)(void *)) 0x7ffff7ffdf60 <_rtld_global+3840>
#gef
#peda와 동일하게 출력 가능하다는데 안나온다; 그래서 직접 찾았다.
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x007ffff7ffd060 → 0x007ffff7ffe170 → 0x00555555400000 → jg 0x555555400047
$rbx : 0x007ffff7ffd060 → 0x007ffff7ffe170 → 0x00555555400000 → jg 0x555555400047
$rcx : 0x1
$rdx : 0x007ffff7de59a0 → push %rbp
$rsp : 0x007fffffffde00 → 0x0000000000000000
$rbp : 0x007fffffffde50 → 0x0000000000000000
$rsi : 0x0
$rdi : 0x0
$rip : 0x007ffff7de5a02 → lea 0x217f5f(%rip), %rdi # 0x7ffff7ffd968 <_rtld_global+2312>
$r8 : 0x0
$r9 : 0x0
$r10 : 0x007ffff7b82cc0 → 0x0002000200020002
$r11 : 0x005555554009a5 → add %ah, 0x64(%rcx)
$r12 : 0x0
$r13 : 0x1
$r14 : 0x007ffff7dd4628 → 0x0000000000000000
$r15 : 0x007ffff7dd0d80 → 0x0000000000000000
$eflags: [zero carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x33 $ss: 0x2b $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00
──────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x007fffffffde00│+0x0000: 0x0000000000000000 ← $rsp
0x007fffffffde08│+0x0008: 0x007ffff7a728a2 → cmp $0xffffffff, %eax
0x007fffffffde10│+0x0010: 0x0000000000000000
0x007fffffffde18│+0x0018: 0x007ffff7dd0760 → 0x00000000fbad2887
0x007fffffffde20│+0x0020: 0x0000000000000000
0x007fffffffde28│+0x0028: 0x0000000000000001
0x007fffffffde30│+0x0030: 0x007ffff7dcf718 → 0x007ffff7dd0d80 → 0x0000000000000000
0x007fffffffde38│+0x0038: 0x0000000000000001
────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x7ffff7de59f1 sub $0x90, %rbx
0x7ffff7de59f8 cmp $0xffffffffffffffff, %r12
0x7ffff7de59fc je 0x7ffff7de5bd0
→ 0x7ffff7de5a02 lea 0x217f5f(%rip), %rdi # 0x7ffff7ffd968 <_rtld_global+2312>
0x7ffff7de5a09 call *0x218551(%rip) # 0x7ffff7ffdf60 <_rtld_global+3840>
0x7ffff7de5a0f mov 0x8(%rbx), %edx
0x7ffff7de5a12 test %edx, %edx
0x7ffff7de5a14 je 0x7ffff7de59e0
0x7ffff7de5a16 mov (%rbx), %rax
────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "ow_rtld", stopped 0x7ffff7de5a02 in ?? (), reason: SINGLE STEP
──────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffff7de5a02 → lea 0x217f5f(%rip), %rdi # 0x7ffff7ffd968 <_rtld_global+2312>
[#1] 0x7ffff7a27041 → jmp 0x7ffff7a26f69
[#2] 0x7ffff7a2713a → exit()
[#3] 0x7ffff7a05b9e → __libc_start_main()
[#4] 0x5555554006fa → _start()
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
물론 함수를 call하는 것이기 때문에 onegadget도 사용 가능하다.
728x90
반응형
'Tips & theory' 카테고리의 다른 글
_IO_FILE Arbitrary Address Read (0) | 2022.08.16 |
---|---|
SROP (0) | 2022.08.15 |
seccomp 요약 (0) | 2022.08.05 |
system call table & calling conventions (0) | 2022.08.05 |
bss 영역 찾기 (0) | 2022.08.05 |