// Name: rtl.c
// Compile: gcc -o rtl rtl.c -fno-PIE -no-pie

#include <stdio.h>
#include <unistd.h>

const char* binsh = "/bin/sh";

int main() {
  char buf[0x30];

  setvbuf(stdin, 0, _IONBF, 0);
  setvbuf(stdout, 0, _IONBF, 0);

  // Add system function to plt's entry
  system("echo 'system@plt");

  // Leak canary
  printf("[1] Leak Canary\\n");
  printf("Buf: ");
  read(0, buf, 0x100);
  printf("Buf: %s\\n", buf);

  // Overwrite return address
  printf("[2] Overwrite return address\\n");
  printf("Buf: ");
  read(0, buf, 0x100);

  return 0;
}

위는 문제의 소스코드다

┌ 241: int main (int argc, char **argv, char **envp);
│           ; var int64_t var_8h @ rbp-0x8
│           ; var int64_t var_40h @ rbp-0x40
│           0x004006f7      55             push rbp
│           0x004006f8      4889e5         mov rbp, rsp
│           0x004006fb      4883ec40       sub rsp, 0x40
│           0x004006ff      64488b042528.  mov rax, qword fs:[0x28]
│           0x00400708      488945f8       mov qword [var_8h], rax
│           0x0040070c      31c0           xor eax, eax
│           0x0040070e      488b055b0920.  mov rax, qword [obj.stdin]  ; obj.stdin__GLIBC_2.2.5
│                                                                      ; [0x601070:8]=0
│           0x00400715      b900000000     mov ecx, 0
│           0x0040071a      ba02000000     mov edx, 2
│           0x0040071f      be00000000     mov esi, 0
│           0x00400724      4889c7         mov rdi, rax
│           0x00400727      e8d4feffff     call sym.imp.setvbuf        ; int setvbuf(FILE*stream, char *buf, int mode, size_t size)
│           0x0040072c      488b052d0920.  mov rax, qword [obj.stdout] ; obj.__TMC_END__
│                                                                      ; [0x601060:8]=0
│           0x00400733      b900000000     mov ecx, 0
│           0x00400738      ba02000000     mov edx, 2
│           0x0040073d      be00000000     mov esi, 0
│           0x00400742      4889c7         mov rdi, rax
│           0x00400745      e8b6feffff     call sym.imp.setvbuf        ; int setvbuf(FILE*stream, char *buf, int mode, size_t size)
│           0x0040074a      bf7c084000     mov edi, str.echo_system_plt ; 0x40087c ; "echo 'system@plt"
│           0x0040074f      b800000000     mov eax, 0
│           0x00400754      e877feffff     call sym.imp.system         ; int system(const char *string)
│           0x00400759      bf8d084000     mov edi, str._1__Leak_Canary ; 0x40088d ; "[1] Leak Canary"
│           0x0040075e      e84dfeffff     call sym.imp.puts           ; int puts(const char *s)
│           0x00400763      bf9d084000     mov edi, str.Buf:_          ; 0x40089d ; "Buf: "
│           0x00400768      b800000000     mov eax, 0
│           0x0040076d      e86efeffff     call sym.imp.printf         ; int printf(const char *format)
│           0x00400772      488d45c0       lea rax, [var_40h]
│           0x00400776      ba00010000     mov edx, 0x100              ; 256
│           0x0040077b      4889c6         mov rsi, rax
│           0x0040077e      bf00000000     mov edi, 0
│           0x00400783      e868feffff     call sym.imp.read           ; ssize_t read(int fildes, void *buf, size_t nbyte)
│           0x00400788      488d45c0       lea rax, [var_40h]
│           0x0040078c      4889c6         mov rsi, rax
│           0x0040078f      bfa3084000     mov edi, str.Buf:__s_n      ; 0x4008a3 ; "Buf: %s\\n"
│           0x00400794      b800000000     mov eax, 0
│           0x00400799      e842feffff     call sym.imp.printf         ; int printf(const char *format)
│           0x0040079e      bfac084000     mov edi, str._2__Overwrite_return_address ; 0x4008ac ; "[2] Overwrite return address"
│           0x004007a3      e808feffff     call sym.imp.puts           ; int puts(const char *s)
│           0x004007a8      bf9d084000     mov edi, str.Buf:_          ; 0x40089d ; "Buf: "
│           0x004007ad      b800000000     mov eax, 0
│           0x004007b2      e829feffff     call sym.imp.printf         ; int printf(const char *format)
│           0x004007b7      488d45c0       lea rax, [var_40h]
│           0x004007bb      ba00010000     mov edx, 0x100              ; 256
│           0x004007c0      4889c6         mov rsi, rax
│           0x004007c3      bf00000000     mov edi, 0
│           0x004007c8      e823feffff     call sym.imp.read           ; ssize_t read(int fildes, void *buf, size_t nbyte)
│           0x004007cd      b800000000     mov eax, 0
│           0x004007d2      488b4df8       mov rcx, qword [var_8h]
│           0x004007d6      6448330c2528.  xor rcx, qword fs:[0x28]
│       ┌─< 0x004007df      7405           je 0x4007e6
│       │   0x004007e1      e8dafdffff     call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
│       └─> 0x004007e6      c9             leave
└           0x004007e7      c3             ret

위는 Radare2로 디스어셈블 한 모습이다.

Untitled

Main 함수에서 선언된 지역변수들의 위치를 나타낸다.

Untitled

보호기법은 Canary, NX, Partial_RelR0 가 걸려있다.

RET주소에 쉘코드를 삼입해도 실행할 수 없으며 Canary로 인해 BOF를 일으킬때 Canary 또한 우회해야 한다.

Untitled