SlideShare a Scribd company logo
1 of 41
Download to read offline
Execution
Angelboy @ bamboofox
Who am I
• Angelboy
• 中央⼤大學碩⼠士班 ADLab
• Bamboofox / HITCON 成員
• 擅⻑⾧長領域 : PWN
Outline
• How programs get run
• Lazy binding
• Global Offset Table
• GOT Hijacking
• We focus on ELF (Executable and Linking
Format)
• What’s happened when we execute an elf file.
• ex : ./hello
How programs get run
Overview of the workflow (static linking)
./hello
fork()
execve(“./hello”,*argv[],*envp[])
sys_execve()
do_execve() search_binary_handler()
load_elf_binary()
_start
main
kernel mode
user mode
Overview of the workflow (dynamic linking)
./hello
fork()
execve(“./hello”,*argv[],*envp[])
sys_execve()
do_execve() search_binary_handler()
load_elf_binary()
ld.so
_start
__libc_start_main _init
kernel mode
user mode
main
• sys_execve()
• 檢查參數 ex: argv , envp
• do_execve()
• 搜尋執⾏行檔位置
• 讀取執⾏行檔前 128 byte 獲取執⾏行檔的資訊
• ex: magic number
How programs get run
• search_binary_handler()
• 利⽤用前⾯面所獲取的資訊來呼叫相對應的 handler
• ex : load_script() 、 load_elf_binary()
How programs get run
• load_elf_binary()
• 檢查及獲取 program header 資訊
• 如果是 dynamic linking 則利⽤用 .interp 這個 section 來確定
loader 路徑
• 將 program header 紀錄的位置 mapping 到 memory 中,ex :
code segment 位置
• 將 sys_execve 的 return address 改為 loader (ld.so) 的entry
point
• static linking 下則會是 elf 的 entry point
How programs get run
• How program maps to virtual memory.
• 在 program header 中
• 記錄著哪些 segment 應該 mapping 到什麼位
置,以及該 segment 的讀寫執⾏行權限
• 記錄哪些 section 屬於哪些 segment
• 當 program mapping 記憶體時會根據權限的
不同來分成好幾個 segment
How programs get run
• How program maps to virtual memory.
How programs get run
權限
mapping 位置
segment 中有哪些 section
• How program maps to virtual memory.
How programs get run
other section
.data
.bss
.got.plt
.rodata
.text
.init
ELF Header
In disk In memory
kernel space
CODE VMA
DATA VMA
HEAP
STACK
R or RX
RW
0x08048000
0x0804a000
0x0804b000
0xbffff4b0
• ld.so
• 載⼊入 elf 所需的 shared library
• 這部分會記錄在 elf 中的 DT_NEED 中
• 初始化 GOT
• 其他相關初始化的動作
• ex : 將 symbol table 合併到 global symbol table
等等
How programs get run
• ld.so 其實是個很複雜的程式,要認真全部講完,
⼀一兩天的時間絕對不夠⽤用
• 有興趣可參考 elf/rtld.c
• 這邊最重要的是在執⾏行程式時,要知道不是從
main 開始的
How programs get run
How programs get run
• _start
• 將下列項⺫⽬目傳給 libc_start_main
• 環境變數起始位置
• .init
• 呼叫 main 之前的初始化⼯工作
• .fini
• 程式結束前的收尾⼯工作
How programs get run
• _libc_start_main
• 執⾏行 .init
• 執⾏行 main
• 執⾏行 .fini
• 執⾏行 exit
Lazy binding
• Dynamic linking 的程式在執⾏行過程中,有些
library 的函式可能到結束都不會執⾏行到
• 所以 ELF 採取 Lazy binding 的機制,在第⼀一次
call library 函式時,才會去尋找函式真正的位置
進⾏行 binding
Global Offset Table
• library 的位置再載⼊入後才決定,因此無法在
compile 後,就知道 library 中的 function 在哪,
該跳去哪
• GOT 為⼀一個函式指標陣列,儲存其他 library 中,
function 的位置,但因 Lazy binding 的機制,並
不會⼀一開始就把正確的位置填上,⽽而是填上⼀一段
plt 位置的 code
18
Global Offset Table
• 當執⾏行到 library 的 function 時才會真正去尋找
function ,最後再把 GOT 中的位置填上真正
function 的位置
19
Global Offset Table
• 分成兩部分
• .got
• 保存全域變數引⽤用位置
• .got.plt
• 保存函式引⽤用位置
20
Global Offset Table
• .got.plt
• 前三項有特別⽤用途
• address of .dynamic
• link_map
• ⼀一個將有引⽤用到的 library 所串成的 linked list
• dl_runtime_resolve
• ⽤用來找出函式位置的函式
• 後⾯面則是程式中 .so 函式引⽤用位置
21
Global Offset Table
• layout
.dynamic
.got
.got.plt
.data
addr of .dynamic
link_map
dl_resolve
printf
put
…
22
.
.
.
call foo@plt
…
Lazy binding
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
23
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
Lazy binding
24
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
因 foo 還沒 call 過
所以 foo 在 .got.plt 中所存的值
會是.plt中的下⼀一⾏行指令位置
所以看起來會像沒有 jmp 過
Lazy binding
25
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
Lazy binding
26
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
Lazy binding
27
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
push link_map
Lazy binding
28
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
jmp dl_runtime_resolve
dl_runtime_resolve (link_map,index)
Lazy binding
29
.
.
.
call foo@plt
…
.text
.got.plt
printf
foo@plt+6
bar
…
..
..
call _fix_up
..
..
ret 0xc
dl_resolve
Lazy binding
30
.
.
.
call foo@plt
…
.text
.got.plt
printf
foo@plt+6
bar
…
..
..
call _fix_up
..
..
ret 0xc
dl_resolve
foo 找到 foo 在 library 的位置後
會填回 .got.plt
Lazy binding
31
.
.
.
call foo@plt
…
Lazy binding
.text
.got.plt
printf
foo@plt+6
bar
…
..
..
call _fix_up
..
..
ret 0xc
dl_resolve
foo
return to foo
32
• 第⼆二次 call foo 時
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
Lazy binding
33
foo
• 第⼆二次 call foo 時
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
Lazy binding
34
foo
Jmp to foo function
How to find the GOT
• objdump -R elf or readelf -r elf
• 為了實作 Lazy binding 的機制 GOT 位置必須是
可寫⼊入的
• 但如果程式有存在任意更改位置的漏洞,便可改
寫 GOT ,造成程式流程的改變
• 也就是控制 eip
GOT Hijacking
• 第⼆二次 call foo 時
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
GOT Hijacking
37
foo
• 第⼆二次 call foo 時
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
GOT Hijacking
38
system
• 第⼆二次 call foo 時
.
.
.
call foo@plt
…
.text
jmp *(foo@GOT)
push index
jmp PLT0
foo@plt
.got.plt
printf
foo@plt+6
bar
…
push *(GOT + 4)
jmp *(GOT + 8)
PLT0
GOT Hijacking
39
system
Jmp to system function
Reference
• Glibc cross reference
• Linux Cross Reference
• 程式設計師的⾃自我修養
Q & A

More Related Content

What's hot

Return to dlresolve
Return to dlresolveReturn to dlresolve
Return to dlresolveAngel Boy
 
Linux Binary Exploitation - Heap Exploitation
Linux Binary Exploitation - Heap Exploitation Linux Binary Exploitation - Heap Exploitation
Linux Binary Exploitation - Heap Exploitation Angel Boy
 
Windows 10 Nt Heap Exploitation (English version)
Windows 10 Nt Heap Exploitation (English version)Windows 10 Nt Heap Exploitation (English version)
Windows 10 Nt Heap Exploitation (English version)Angel Boy
 
Linux Binary Exploitation - Return-oritend Programing
Linux Binary Exploitation - Return-oritend ProgramingLinux Binary Exploitation - Return-oritend Programing
Linux Binary Exploitation - Return-oritend ProgramingAngel Boy
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented ProgrammingAngel Boy
 
ROP 輕鬆談
ROP 輕鬆談ROP 輕鬆談
ROP 輕鬆談hackstuff
 
Tcache Exploitation
Tcache ExploitationTcache Exploitation
Tcache ExploitationAngel Boy
 
TDOH x 台科 pwn課程
TDOH x 台科 pwn課程TDOH x 台科 pwn課程
TDOH x 台科 pwn課程Weber Tsai
 
MacOS memory allocator (libmalloc) Exploitation
MacOS memory allocator (libmalloc) ExploitationMacOS memory allocator (libmalloc) Exploitation
MacOS memory allocator (libmalloc) ExploitationAngel Boy
 
Linux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old SecretsLinux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old SecretsBrendan Gregg
 
台科逆向簡報
台科逆向簡報台科逆向簡報
台科逆向簡報耀德 蔡
 
NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27Sheng-Hao Ma
 
DeathNote of Microsoft Windows Kernel
DeathNote of Microsoft Windows KernelDeathNote of Microsoft Windows Kernel
DeathNote of Microsoft Windows KernelPeter Hlavaty
 
Linux Performance Profiling and Monitoring
Linux Performance Profiling and MonitoringLinux Performance Profiling and Monitoring
Linux Performance Profiling and MonitoringGeorg Schönberger
 
twlkh-linux-vsyscall-and-vdso
twlkh-linux-vsyscall-and-vdsotwlkh-linux-vsyscall-and-vdso
twlkh-linux-vsyscall-and-vdsoViller Hsiao
 
Container Performance Analysis
Container Performance AnalysisContainer Performance Analysis
Container Performance AnalysisBrendan Gregg
 
Linux 4.x Tracing: Performance Analysis with bcc/BPF
Linux 4.x Tracing: Performance Analysis with bcc/BPFLinux 4.x Tracing: Performance Analysis with bcc/BPF
Linux 4.x Tracing: Performance Analysis with bcc/BPFBrendan Gregg
 

What's hot (20)

Return to dlresolve
Return to dlresolveReturn to dlresolve
Return to dlresolve
 
Linux Binary Exploitation - Heap Exploitation
Linux Binary Exploitation - Heap Exploitation Linux Binary Exploitation - Heap Exploitation
Linux Binary Exploitation - Heap Exploitation
 
Windows 10 Nt Heap Exploitation (English version)
Windows 10 Nt Heap Exploitation (English version)Windows 10 Nt Heap Exploitation (English version)
Windows 10 Nt Heap Exploitation (English version)
 
Linux Binary Exploitation - Return-oritend Programing
Linux Binary Exploitation - Return-oritend ProgramingLinux Binary Exploitation - Return-oritend Programing
Linux Binary Exploitation - Return-oritend Programing
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented Programming
 
ROP 輕鬆談
ROP 輕鬆談ROP 輕鬆談
ROP 輕鬆談
 
Tcache Exploitation
Tcache ExploitationTcache Exploitation
Tcache Exploitation
 
TDOH x 台科 pwn課程
TDOH x 台科 pwn課程TDOH x 台科 pwn課程
TDOH x 台科 pwn課程
 
MacOS memory allocator (libmalloc) Exploitation
MacOS memory allocator (libmalloc) ExploitationMacOS memory allocator (libmalloc) Exploitation
MacOS memory allocator (libmalloc) Exploitation
 
Linux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old SecretsLinux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old Secrets
 
台科逆向簡報
台科逆向簡報台科逆向簡報
台科逆向簡報
 
NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27
 
DeathNote of Microsoft Windows Kernel
DeathNote of Microsoft Windows KernelDeathNote of Microsoft Windows Kernel
DeathNote of Microsoft Windows Kernel
 
Linux Performance Profiling and Monitoring
Linux Performance Profiling and MonitoringLinux Performance Profiling and Monitoring
Linux Performance Profiling and Monitoring
 
twlkh-linux-vsyscall-and-vdso
twlkh-linux-vsyscall-and-vdsotwlkh-linux-vsyscall-and-vdso
twlkh-linux-vsyscall-and-vdso
 
Container Performance Analysis
Container Performance AnalysisContainer Performance Analysis
Container Performance Analysis
 
Linux 4.x Tracing: Performance Analysis with bcc/BPF
Linux 4.x Tracing: Performance Analysis with bcc/BPFLinux 4.x Tracing: Performance Analysis with bcc/BPF
Linux 4.x Tracing: Performance Analysis with bcc/BPF
 
B-link-tree
B-link-treeB-link-tree
B-link-tree
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
x86
x86x86
x86
 

Similar to Execution

Vim hacks
Vim hacksVim hacks
Vim hacksXuYj
 
現代 IT 人一定要知道的 Ansible 自動化組態技巧
現代 IT 人一定要知道的 Ansible 自動化組態技巧現代 IT 人一定要知道的 Ansible 自動化組態技巧
現代 IT 人一定要知道的 Ansible 自動化組態技巧Chu-Siang Lai
 
Yet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upYet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upWen-Tien Chang
 
Automate with Ansible basic (3/e)
Automate with Ansible basic (3/e)Automate with Ansible basic (3/e)
Automate with Ansible basic (3/e)Chu-Siang Lai
 
用Raspberry PI學Linux驅動程式
用Raspberry PI學Linux驅動程式用Raspberry PI學Linux驅動程式
用Raspberry PI學Linux驅動程式Stanley Ho
 
Erlang Practice
Erlang PracticeErlang Practice
Erlang Practicelitaocheng
 
Lua 语言介绍
Lua 语言介绍Lua 语言介绍
Lua 语言介绍gowell
 
Python 入门
Python 入门Python 入门
Python 入门kuco945
 
Introduce to Linux command line
Introduce to Linux command lineIntroduce to Linux command line
Introduce to Linux command lineWen Liao
 
Android C Library: Bionic 成長計畫
Android C Library: Bionic 成長計畫Android C Library: Bionic 成長計畫
Android C Library: Bionic 成長計畫Kito Cheng
 
Openshift by mtchang
Openshift by mtchangOpenshift by mtchang
Openshift by mtchangChang Mt
 
Learning python in the motion picture industry by will zhou
Learning python in the motion picture industry   by will zhouLearning python in the motion picture industry   by will zhou
Learning python in the motion picture industry by will zhouWill Zhou
 
Python 于 webgame 的应用
Python 于 webgame 的应用Python 于 webgame 的应用
Python 于 webgame 的应用勇浩 赖
 
Strace debug
Strace debugStrace debug
Strace debugluo jing
 
为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)Kris Mok
 
Effective linux.1.(commandline)
Effective linux.1.(commandline)Effective linux.1.(commandline)
Effective linux.1.(commandline)wang hongjiang
 
程式設計師的自我修養 Chapter 10 記憶體
程式設計師的自我修養 Chapter 10 記憶體程式設計師的自我修養 Chapter 10 記憶體
程式設計師的自我修養 Chapter 10 記憶體Shu-Yu Fu
 
Continuous Delivery with Ansible x GitLab CI
Continuous Delivery with Ansible x GitLab CIContinuous Delivery with Ansible x GitLab CI
Continuous Delivery with Ansible x GitLab CIChu-Siang Lai
 
Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Wen-Tien Chang
 

Similar to Execution (20)

Vim hacks
Vim hacksVim hacks
Vim hacks
 
現代 IT 人一定要知道的 Ansible 自動化組態技巧
現代 IT 人一定要知道的 Ansible 自動化組態技巧現代 IT 人一定要知道的 Ansible 自動化組態技巧
現代 IT 人一定要知道的 Ansible 自動化組態技巧
 
Yet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upYet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom up
 
Automate with Ansible basic (3/e)
Automate with Ansible basic (3/e)Automate with Ansible basic (3/e)
Automate with Ansible basic (3/e)
 
用Raspberry PI學Linux驅動程式
用Raspberry PI學Linux驅動程式用Raspberry PI學Linux驅動程式
用Raspberry PI學Linux驅動程式
 
Erlang Practice
Erlang PracticeErlang Practice
Erlang Practice
 
Lua 语言介绍
Lua 语言介绍Lua 语言介绍
Lua 语言介绍
 
Python 入门
Python 入门Python 入门
Python 入门
 
Introduce to Linux command line
Introduce to Linux command lineIntroduce to Linux command line
Introduce to Linux command line
 
Rootkit 101
Rootkit 101Rootkit 101
Rootkit 101
 
Android C Library: Bionic 成長計畫
Android C Library: Bionic 成長計畫Android C Library: Bionic 成長計畫
Android C Library: Bionic 成長計畫
 
Openshift by mtchang
Openshift by mtchangOpenshift by mtchang
Openshift by mtchang
 
Learning python in the motion picture industry by will zhou
Learning python in the motion picture industry   by will zhouLearning python in the motion picture industry   by will zhou
Learning python in the motion picture industry by will zhou
 
Python 于 webgame 的应用
Python 于 webgame 的应用Python 于 webgame 的应用
Python 于 webgame 的应用
 
Strace debug
Strace debugStrace debug
Strace debug
 
为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)为啥别读HotSpot VM的源码(2012-03-03)
为啥别读HotSpot VM的源码(2012-03-03)
 
Effective linux.1.(commandline)
Effective linux.1.(commandline)Effective linux.1.(commandline)
Effective linux.1.(commandline)
 
程式設計師的自我修養 Chapter 10 記憶體
程式設計師的自我修養 Chapter 10 記憶體程式設計師的自我修養 Chapter 10 記憶體
程式設計師的自我修養 Chapter 10 記憶體
 
Continuous Delivery with Ansible x GitLab CI
Continuous Delivery with Ansible x GitLab CIContinuous Delivery with Ansible x GitLab CI
Continuous Delivery with Ansible x GitLab CI
 
Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀
 

Execution

  • 2. Who am I • Angelboy • 中央⼤大學碩⼠士班 ADLab • Bamboofox / HITCON 成員 • 擅⻑⾧長領域 : PWN
  • 3. Outline • How programs get run • Lazy binding • Global Offset Table • GOT Hijacking
  • 4. • We focus on ELF (Executable and Linking Format) • What’s happened when we execute an elf file. • ex : ./hello How programs get run
  • 5. Overview of the workflow (static linking) ./hello fork() execve(“./hello”,*argv[],*envp[]) sys_execve() do_execve() search_binary_handler() load_elf_binary() _start main kernel mode user mode
  • 6. Overview of the workflow (dynamic linking) ./hello fork() execve(“./hello”,*argv[],*envp[]) sys_execve() do_execve() search_binary_handler() load_elf_binary() ld.so _start __libc_start_main _init kernel mode user mode main
  • 7. • sys_execve() • 檢查參數 ex: argv , envp • do_execve() • 搜尋執⾏行檔位置 • 讀取執⾏行檔前 128 byte 獲取執⾏行檔的資訊 • ex: magic number How programs get run
  • 8. • search_binary_handler() • 利⽤用前⾯面所獲取的資訊來呼叫相對應的 handler • ex : load_script() 、 load_elf_binary() How programs get run
  • 9. • load_elf_binary() • 檢查及獲取 program header 資訊 • 如果是 dynamic linking 則利⽤用 .interp 這個 section 來確定 loader 路徑 • 將 program header 紀錄的位置 mapping 到 memory 中,ex : code segment 位置 • 將 sys_execve 的 return address 改為 loader (ld.so) 的entry point • static linking 下則會是 elf 的 entry point How programs get run
  • 10. • How program maps to virtual memory. • 在 program header 中 • 記錄著哪些 segment 應該 mapping 到什麼位 置,以及該 segment 的讀寫執⾏行權限 • 記錄哪些 section 屬於哪些 segment • 當 program mapping 記憶體時會根據權限的 不同來分成好幾個 segment How programs get run
  • 11. • How program maps to virtual memory. How programs get run 權限 mapping 位置 segment 中有哪些 section
  • 12. • How program maps to virtual memory. How programs get run other section .data .bss .got.plt .rodata .text .init ELF Header In disk In memory kernel space CODE VMA DATA VMA HEAP STACK R or RX RW 0x08048000 0x0804a000 0x0804b000 0xbffff4b0
  • 13. • ld.so • 載⼊入 elf 所需的 shared library • 這部分會記錄在 elf 中的 DT_NEED 中 • 初始化 GOT • 其他相關初始化的動作 • ex : 將 symbol table 合併到 global symbol table 等等 How programs get run
  • 14. • ld.so 其實是個很複雜的程式,要認真全部講完, ⼀一兩天的時間絕對不夠⽤用 • 有興趣可參考 elf/rtld.c • 這邊最重要的是在執⾏行程式時,要知道不是從 main 開始的 How programs get run
  • 15. How programs get run • _start • 將下列項⺫⽬目傳給 libc_start_main • 環境變數起始位置 • .init • 呼叫 main 之前的初始化⼯工作 • .fini • 程式結束前的收尾⼯工作
  • 16. How programs get run • _libc_start_main • 執⾏行 .init • 執⾏行 main • 執⾏行 .fini • 執⾏行 exit
  • 17. Lazy binding • Dynamic linking 的程式在執⾏行過程中,有些 library 的函式可能到結束都不會執⾏行到 • 所以 ELF 採取 Lazy binding 的機制,在第⼀一次 call library 函式時,才會去尋找函式真正的位置 進⾏行 binding
  • 18. Global Offset Table • library 的位置再載⼊入後才決定,因此無法在 compile 後,就知道 library 中的 function 在哪, 該跳去哪 • GOT 為⼀一個函式指標陣列,儲存其他 library 中, function 的位置,但因 Lazy binding 的機制,並 不會⼀一開始就把正確的位置填上,⽽而是填上⼀一段 plt 位置的 code 18
  • 19. Global Offset Table • 當執⾏行到 library 的 function 時才會真正去尋找 function ,最後再把 GOT 中的位置填上真正 function 的位置 19
  • 20. Global Offset Table • 分成兩部分 • .got • 保存全域變數引⽤用位置 • .got.plt • 保存函式引⽤用位置 20
  • 21. Global Offset Table • .got.plt • 前三項有特別⽤用途 • address of .dynamic • link_map • ⼀一個將有引⽤用到的 library 所串成的 linked list • dl_runtime_resolve • ⽤用來找出函式位置的函式 • 後⾯面則是程式中 .so 函式引⽤用位置 21
  • 22. Global Offset Table • layout .dynamic .got .got.plt .data addr of .dynamic link_map dl_resolve printf put … 22
  • 23. . . . call foo@plt … Lazy binding .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 23
  • 24. . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 Lazy binding 24
  • 25. . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 因 foo 還沒 call 過 所以 foo 在 .got.plt 中所存的值 會是.plt中的下⼀一⾏行指令位置 所以看起來會像沒有 jmp 過 Lazy binding 25
  • 26. . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 Lazy binding 26
  • 27. . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 Lazy binding 27
  • 28. . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 push link_map Lazy binding 28
  • 29. . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 jmp dl_runtime_resolve dl_runtime_resolve (link_map,index) Lazy binding 29
  • 31. . . . call foo@plt … .text .got.plt printf foo@plt+6 bar … .. .. call _fix_up .. .. ret 0xc dl_resolve foo 找到 foo 在 library 的位置後 會填回 .got.plt Lazy binding 31
  • 32. . . . call foo@plt … Lazy binding .text .got.plt printf foo@plt+6 bar … .. .. call _fix_up .. .. ret 0xc dl_resolve foo return to foo 32
  • 33. • 第⼆二次 call foo 時 . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 Lazy binding 33 foo
  • 34. • 第⼆二次 call foo 時 . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 Lazy binding 34 foo Jmp to foo function
  • 35. How to find the GOT • objdump -R elf or readelf -r elf
  • 36. • 為了實作 Lazy binding 的機制 GOT 位置必須是 可寫⼊入的 • 但如果程式有存在任意更改位置的漏洞,便可改 寫 GOT ,造成程式流程的改變 • 也就是控制 eip GOT Hijacking
  • 37. • 第⼆二次 call foo 時 . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 GOT Hijacking 37 foo
  • 38. • 第⼆二次 call foo 時 . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 GOT Hijacking 38 system
  • 39. • 第⼆二次 call foo 時 . . . call foo@plt … .text jmp *(foo@GOT) push index jmp PLT0 foo@plt .got.plt printf foo@plt+6 bar … push *(GOT + 4) jmp *(GOT + 8) PLT0 GOT Hijacking 39 system Jmp to system function
  • 40. Reference • Glibc cross reference • Linux Cross Reference • 程式設計師的⾃自我修養
  • 41. Q & A