what is _environ

https://dreamhack.io/wargame/challenges/363

pwntools를 풀다 보면 stack leak을 해야하는 상황이 반드시 오게 된다. 그때 사용할 수 있는 방법 중 하나가 바로 _environ 변수의 값을 leak 하는 것이다.

Python
root@a0b2cea1050c:/home/environ/environ# objdump -tT libc.so.6 | grep environ
0000000000221200  w   DO .bss	0000000000000008  GLIBC_2.2.5 _environ
0000000000221200 g    DO .bss	0000000000000008  GLIBC_2.2.5 __environ
0000000000221200  w   DO .bss	0000000000000008  GLIBC_2.2.5 environ
root@a0b2cea1050c:/home/environ/environ# 

다음과 같이 libc 파일 bss 섹션에 위치하며 _environ __environ 다 똑같은 심볼이다.

Python
$1 = (char **) 0x7fffffffe698
pwndbg> vmmap 0x7fffffffe698
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
             Start                End Perm     Size Offset File
    0x7ffff7ffd000     0x7ffff7fff000 rw-p     2000  39000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
►   0x7ffffffde000     0x7ffffffff000 rw-p    21000      0 [stack] +0x20698

gdb로 봤을때 _environ의 값은 stack 영역을 가르키고 있다. 따라서 이 값을 알 수 있다면 stack leak 이 가능하고 offset을 구해서 내가 원하는 스택의 위치를 알 수 있다.

그렇다면 어떻게 이 _environ 의 값을 알 수 있을까? 가장 쉬운 방법은 libc_base를 통해 다른 값으로 부터 알아내는 것이다.

예를 들어 stdout 값을 알 수 있다면

Python
iofile_stdout = libc_e.symbols[b'_IO_2_1_stdout_']
__environ = libc_e.symbols[b'__environ']

print(iofile_stdout - __environ)

다음과 같이 Pwntools로 바로 offset을 알아 낼 수 있다.

그런데.. 문제가 생겼다.