# pwn ## 環境配置 ### pwn ⼯具懶⼈包 ``` git clone https://github.com/r888800009/CTF-tool.git cd CTF-tool/pwn_docker ./setup_docker.sh 20.04 docker run --privileged --rm -it\v $(pwd):/work ctf_ubuntu_20.04 ``` ### Ghidra Download: https://github.com/NationalSecurityAgency/ghidra/releases ``` unzip ghidra_*_PUBLIC_*.zip sudo apt-get install default-jdk /ghidraRun ``` ## Lab readelf readelf 讀取 /bin/sh 的 * ELF Header * Section Header * Program Header ``` readelf -h /bin/sh ```  ``` readelf -S /bin/sh ```  ``` readelf -l /bin/sh ```  下方Segment Sections的00,01,02都對着Program Header的Type,PHDR,INTERP Example: 找出.text在上方Program Header的哪裏? 可見.text在下方的Segment Sections 03的位置,而03剛好對着LOAD 0x0000000000000000 ## gcc參數 * -o * 制定目標名稱 * -l * 制定編譯的時候使用的庫 * -no-pie * 關閉PIE保護 * -fno-stack-protector * 關閉canary保護 ## gdb指令 ### 常用 * run / start * start 會停在 main(),run 會直接執⾏完 * run 也可以傳入⼀些參數 * attach <pid> * 如果要 attach 需要⽤ sudo 開啟 gdb 才有 * ptrace 的權限 * b *0x1234 * 在 0x1234 這個地址設定斷點 * 也可以直接 b main 斷在 main * 單步執⾏ * si 進入 function * ni 不進入 function * c * 程式繼續執⾏ * finish * 完成⽬前的 function,讓 gdb 停在 ret 這個指 令上⾯ * bt * backtrace 顯⽰⽬前的函數 Call stack * q * 退出 gdb 不過 ctrl+d 也是可以的 * ctrl+r * 可以快速搜尋打過的指令 * print <*addr/symbol> * 顯⽰特定地址內容 * set $rip=0x1234 * 將⽬前的 rip 改成 0x1234 * set follow-fork-mode <mode> * 可以是 parent 或 child ### Plugin * context * 顯⽰ stack / code / registers / trace 這些視窗 * vmmap * 顯⽰ virtual memory layout * i proc mappings * 每個 page 的 * 權限 * 起點與結束位置 * page 所載入的 image * checksec * 顯⽰⽬前保護機制哪些有啟⽤ * telescope * 打印出記憶體內容,預設是 $rsp * telescope $rsp+0x10 * telescope $fs_base 可以查詢 TLS * search-pattern \<pattern> / search \<pattern> * 搜尋記憶體是否有特殊數值或字串 ## Lab stack-frame and fork_canary 1. 熟悉 gdb 與 gef / pwndbg 插件,並且認識 process 1. https://github.com/r888800009/pwn-labs/blob/main/stack-frame 1. 在 gdb 外⾯ attach 另外⼀個 /bin/sh 的 process 1. stack-frame * 練習斷點 * 進入 puts() 函數裡⾯,之後透過 finish 出來 * 透過 vmmap 找出 libc.so 的 base address * 找出 "/bin/sh" 這個字串 * 在 main 直接跳過 puts 不要輸出顯⽰ 1. fork_canary * 這個程式會 fork ⼀個 process,並且把 parent 的 * canary print 出來,請猜猜看 child 的 canary * 如果猜到的話,請解釋怎麼猜的。 * https://github.com/r888800009/pwn-labs/blob/main/fork_canary ``` gdb /bin/sh start ```  --- 如果要在0x555555555150 <main+23> mov rdi, rax設breakpoint可以使用 ``` b *Address example: b *0x555555555150 ``` 如下圖  ### stack-frame 在\<puts@plt>設breakpoint然後一直si到沒plt為止就進到puts()裏了  用vmmap看出libc.so在0x007ffff7dcd000 ... r-- .../x86_64-linux-gnu/libc-2.31.so  使用search-pattern "/bin/sh"  在\<puts@plt>前一行設breakpoint和用set $rip=xxxx把rip設在\<puts@plt>後一行,就能跳過puts執行下一行。 如果沒跳過的話會輸出hello world ### fork canary ``` set follow-fork-mode parent canary ```   --- 可以看見child 和 parent canary是一樣的,因為fork的時候,child會複製一樣的東西出來,包括Physical memory也指向同一個。如果child裏有改動的話,就需要從原先在physical memory的值再複製一份做更改。  ## Lab Mitigations https://github.com/r888800009/pwn-labs/blob/main/mitigations.c 1. 了解常⾒ CTF 保護機制等等 1. ⽬標 (將解法打到共筆上⾯) * 編譯沒有 PIE 但是有 canary 保護的 ELF * 執⾏四次 ./mitigations,並且記錄每次 libc 的位置 * Checksec * 檢視編譯好的 mitigations 有限制哪些 syscall * 透過 gdb 找出 canary 的數值 * 透過搜尋 canary 找出 TLS 的位置 --- 編譯沒有 PIE 但是有 canary 保護的 ELF 編譯的時候會出現警告訊息,因為程式中使用了不安全的gets,可以無視 ``` gcc -no-pie mitigations.c -l seccomp -o mitigations ```  雖然已經關閉了PIE但是因為還有canary所以libc的位置還是會隨機  ``` seccomp-tools dump ./mitigations ``` syscall為如下 
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up