http://v0ids3curity.blogspot.kr/2014/12/return-to-vdso-using-elf-auxiliary.html
2016/11/21 - [System/etc] - Memory Layout, Segment / Stack layout
Linux Stack Layout with Auxiliary Vectors
```c
0x7fffffffe0e8: 0x00007ffff7a36f45 ( main's ret )
0x7fffffffe0f0: 0x0000000000000000 ( argc )
0x7fffffffe0f8: 0x00007fffffffe1c8 ( **argv )
....................
0x7fffffffe1c0: 0x0000000000000000 ( argc )
0x7fffffffe1c8: 0x00007fffffffe5a7 ( argv[0] )
0x7fffffffe1d0: 0x0000000000000000 ( last argv[n] == NULL )
0x7fffffffe1d8: 0x00007fffffffe5d5 ( envp[0] )
0x7fffffffe1e0: 0x00007fffffffe67f ( envp[1] )
..........envp[]..........
0x7fffffffe420: 0x0000000000000000 ( last envp[n] == NULL )
/***** auxv[] *****/
key value
0x7fffffffe428: 0x0000000000000021 0x00007ffff7ffa000 // AT_SYSINFO_EHDR
0x7fffffffe438: 0x0000000000000010 0x000000001f8bfbff
0x7fffffffe448: 0x0000000000000006 0x0000000000001000
0x7fffffffe458: 0x0000000000000011 0x0000000000000064
0x7fffffffe468: 0x0000000000000003 0x0000000000400040
0x7fffffffe478: 0x0000000000000004 0x0000000000000038
0x7fffffffe488: 0x0000000000000005 0x0000000000000009
0x7fffffffe498: 0x0000000000000007 0x00007ffff7dda000
0x7fffffffe4a8: 0x0000000000000008 0x0000000000000000
0x7fffffffe4b8: 0x0000000000000009 0x0000000000400490
0x7fffffffe4c8: 0x000000000000000b 0x00000000000003e8
0x7fffffffe4d8: 0x000000000000000c 0x00000000000003e8
0x7fffffffe4e8: 0x000000000000000d 0x00000000000003e8
0x7fffffffe4f8: 0x000000000000000e 0x00000000000003e8
0x7fffffffe508: 0x0000000000000017 0x0000000000000000
0x7fffffffe518: 0x0000000000000019 0x00007fffffffe559 // AT_RANDOM
0x7fffffffe528: 0x000000000000001f 0x00007fffffffefca
0x7fffffffe538: 0x000000000000000f 0x00007fffffffe569
0x7fffffffe548: 0x0000000000000000 0x0000000000000000
0x7fffffffe558
....................
0x7fffffffe5a7: "filename" ( argv strings )
..........
0x7fffffffe5d5: "ENV=value" ( envp strings )
....................
program name (== argv[0] string )
NULL
....................
```
```c
$ set env LD_SHOW_AUXV=1
$ r
AT_SYSINFO_EHDR: 0x7ffff7ffa000 // VDSO addr
AT_HWCAP: 1f8bfbff
AT_PAGESZ: 4096
AT_CLKTCK: 100
AT_PHDR: 0x400040
AT_PHENT: 56
AT_PHNUM: 9
AT_BASE: 0x7ffff7dda000
AT_FLAGS: 0x0
AT_ENTRY: 0x400490 // Entry point of program
AT_UID: 1000
AT_EUID: 1000
AT_GID: 1000
AT_EGID: 1000
AT_SECURE: 0 // secure-execution mode
AT_RANDOM: 0x7fffffffe559 // point to end of AUXV table
AT_EXECFN: /home/ubuntu/workspace/study/heap/fastbin_dup
AT_PLATFORM: x86_64
```
`` AT_RANDOM``을 이용해 stack offset을 계산하는 것은 remote라면 거의 불가능하다. 서버 측 쉘의 환경변수가 얼마나 있는지도 모르고, 각 stack frame size같은 것도 정확히 맞출 수 없기 때문에 어느 정도는 추측해야 한다.
sys_read-sys_write leak
#1 sys_read
```
rax : 0x0 / rsi : (stack) / rdi : (stdin, 0) / rdx : size ( x86_64 )
```
* `` rdi``에서 읽어서, `` rsi``에 쓰게 된다. 결과적으로 read하는 곳이 `` stdin``이라 `` rdi : stdin``
위와 같은 상태에서 `` syscall`` 해서 `` sys_read``를 호출한 다음 `` rax=0x1``로 만들기 위해 `` \n``만 전송한다.
#2 sys_write
`` sys_read``가 끝난 이후 레지스터 상태는 다음과 같다.
```
rax : 0x1 / rsi : (stack) / rdi : (stdin, 0) / rdx : size ( x86_64 )
```
* `` rsi``에서 읽어서, `` rdi``에 쓰게 된다. 결과적으로 write하는 곳이 `` stdin``이라 `` rdi : stdin``
stdin이든 stdout이든 stderr이든 입출력에 아무거나 사용해도 되기 때문에 이대로 `` sys_write``를 호출하면 `` sys_read``에서 데이터를 저장해놓은 지점부터 `` size``만큼 leak.
이를 `` AUXV`` leak에 사용할 수 있다.
Return to vDSO
gadget
server 측에서 사용하는 vDSO page를 알고 있을 때 사용할 수 있기 때문에 제약이 꽤 크다. server OS를 알고 있다면 vDSO page도 알아낼 수는 있을 듯.
64bit에서는 parameter push를 위해 `` rdi, rsi, rdx``를 조작할 수 있어야 하는데, Ubuntu 14.04.5 LTS에는 다음을 제외하면 적당한 gadget이 없다.
```c
0x7ffff7ffa9d6: syscall
0x7ffff7ffa9d8: pop rbx
0x7ffff7ffa9d9: pop rbp
0x7ffff7ffa9da: ret
```
아무튼, vDSO를 사용할 수 있는 환경이라면 이런 유용한 gadget들을 찾아보는게 도움이 된다.
vDSO addr
- ``c fork()``하는 경우 vDSO addr이 매번 같기 때문에 `` AT_SYSINFO_EHDR`` leak 하면 바로 알아낼 수 있다.
- vDSO page는 random하게 결정되지만, randomize range가 그리 크지 않아 brute force가 불가능한 수준은 아닌 듯.
https://github.com/umbum/pwn/blob/master/vdso/entropy.py