# Web SQL injection Lab12
盲注方式:利用條件為真時觸發錯誤(例如除以 0),根據是否出現錯誤訊息(HTTP 500)來判斷條件真假
目標:找出 administrator 的密碼,並登入
---
一樣先進入網站並攔截請求。


一樣先測試網站的反應,嘗試用 `'` 和 `''` 來測試。


有此可知,錯誤語法有效,所以接著來試 Oracle 的 SELECT 語法,先來個基本的查詢語法。
```
'||(SELECT '' FROM dual)||'
```

一樣是 200 ,所以確認可以使用,再來就是查詢 user 表跟使用者存不存在。
```
||(SELECT '' FROM users WHERE ROWNUM = 1)||
```
從 users 資料表中選取一個空字串 '',條件是 ROWNUM = 1。
- users:假設這是一張使用者資料表。
- ROWNUM = 1:Oracle 的方式,用來限制只拿回第一筆資料。
- SELECT '':不是查特定欄位資料,而是查「空字串」,但透過 users 表來取出這筆空字串(只是為了從某筆資料中「掛」一段空值出來,用於語法合法化)。

一樣是 200 ,所以 user 表存在。
而重點來了,題目說要==透過錯誤判斷真假==,所以使用 `CASE WHEN` 和 `TO_CHAR(1/0)`:
- 條件為真 ➜ 執行除以零 ➜ 觸發錯誤(HTTP 500)
- 條件為假 ➜ 執行空字串 ➜ 無錯誤(HTTP 200)
```
||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||
```
查詢來自 users 表、符合條件 `username='administrator'` 的資料,並使用 `CASE WHEN` 條件式。
`CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END`
這段是邏輯判斷,如果 1=1(永遠為真):
→ 就執行 `TO_CHAR(1/0)`
→ 這會導致 除以 0 錯誤,並觸發 Oracle 的錯誤處理機制。
否則就回傳空字串 `''` 。
:::success
這是**透過錯誤訊息來判斷資料庫內容**的一種技巧,特別是在 Oracle 資料庫下。
用法情境:
你有一個 injection 點,但沒有回傳資料,只會回傳**有沒有錯誤**。
所以可以寫:
```
CASE WHEN (某條件為真) THEN 觸發錯誤 ELSE 回傳空字串
```
藉由是否出錯,來判斷那個條件是真還是假。
---
### 簡單來說:
你是個八卦王,要偷聽別人的秘密,你(攻擊者)偷偷混進一場神祕聚會,裡面有個櫃子寫著「只有管理員的資訊才放這裡」(username='administrator')。但櫃子上鎖,不能直接打開,也不能問:「欸他密碼是什麼?」,那這時候該怎麼辦?你想到一個聰明的方法:
### 情境邏輯
對櫃子問一個問題,比如:
「如果管理員的密碼第一個字是 s,你就爆炸;不是的話就安靜。」
- 如果真的爆炸 💥(系統報錯):你知道答案是「是」。
- 如果沒聲音 🤫:你知道答案是「不是」。
你不用打開櫃子、也不用看到密碼本,但透過系統的「反應」,就能一點一滴把秘密拼湊出來。
### 這句話在做什麼?
`CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END`
→「如果條件成立,我就除以 0(讓系統炸掉);否則就回傳空白(安靜沒事)」
### 生活化翻譯
| 原本語法 | 白話解釋 |
| -------- | -------- |
| (1=1) | 我問一個一定會成立的問題(為了測試) |
| TO_CHAR(1/0) | 叫系統炸一下給我看 |
| ELSE '' | 不炸,就什麼都不說 |
| FROM users WHERE username='administrator' | 針對管理員那一筆資料做測試 |
:::
了解原理後,後面就跟上一題一樣猜密碼長度跟爆破密碼。
```
||(SELECT CASE WHEN LENGTH(password)>1 THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||
```
如果密碼長度大於 1 的話就會發生 500 狀態碼(依此類推),透過數字爆破後,一樣也是確定密碼為 20 位長的密碼。


```
||(SELECT CASE WHEN SUBSTR(password,1,1)='§a§' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||
```

:::danger
要爆破的密碼位數
:::
:::success
要填充的位置
:::
:::info
要爆破的字元表(0 ~ 9、a ~ z)
:::
如果密碼猜對的話就會發生 500 狀態碼(依此類推),透過爆破後,帳密為:
`administrator:ojzpit5atwq38sbvuixn`

---