一、實(shí)驗(yàn)?zāi)康?/h2>
????????SQL 注入是一種代碼注入技術(shù),可利用 Web 應(yīng)用程序和數(shù)據(jù)庫(kù)服務(wù)器之間接口中的漏洞。當(dāng)用戶的輸入在發(fā)送到后端數(shù)據(jù)庫(kù)服務(wù)器之前未在 Web 應(yīng)用程序中正確檢查時(shí),該漏洞就存在。
????????許多 Web 應(yīng)用程序從用戶處獲取輸入,然后使用這些輸入構(gòu)建 SQL 查詢,以便從數(shù)據(jù)庫(kù)獲取信息。Web 應(yīng)用程序還使用 SQL 查詢將信息存儲(chǔ)在數(shù)據(jù)庫(kù)中。這些都是開發(fā) Web 應(yīng)用程序的常見做法。當(dāng) SQL 查詢沒有仔細(xì)構(gòu)建時(shí),可能會(huì)出現(xiàn) SQL 注入漏洞。SQL 注入是 Web 應(yīng)用程序上最常見的攻擊之一。
????????在此次實(shí)驗(yàn)中,我們創(chuàng)建了一個(gè)易受 SQL 注入攻擊的 Web 應(yīng)用程序。我們的 Web 應(yīng)用程序包括許多Web開發(fā)人員所犯的常見錯(cuò)誤。我們實(shí)驗(yàn)的目標(biāo)是找到利用 SQL 注入漏洞的方法,演示攻擊可能造成的損害,并掌握有助于抵御此類攻擊的技術(shù)。
本實(shí)驗(yàn)涵蓋以下幾個(gè)內(nèi)容:SQL 語句:SELECT 和UPDATE 語句;SQL 注入;Prepared statement
二、實(shí)驗(yàn)環(huán)境
????????該實(shí)驗(yàn)已在SEED Ubuntu 20.04 VM上進(jìn)行了測(cè)試。您可以從 SEED 網(wǎng)站下載VM影像,并在自己的計(jì)算機(jī)上運(yùn)行 SEED VM。此外,大多數(shù) SEED 實(shí)驗(yàn)都可以在云上進(jìn)行,您也可以按照我們的指示在云上創(chuàng)建SEED VM。
-
實(shí)驗(yàn)設(shè)置文件
????????可以根據(jù)一下路徑引導(dǎo),在對(duì)應(yīng)的網(wǎng)站下載安裝相對(duì)應(yīng)的數(shù)據(jù)壓縮包,或者在我們自己的虛擬機(jī)中輸入路徑下載該文件,兩種方式在后續(xù)都會(huì)展示。
作者網(wǎng)站下載:
首先進(jìn)入鏈接SEED Project:
展示如下:
??????? 此時(shí)我們點(diǎn)擊頁面展示中的labsetup.zip即可下載此次實(shí)驗(yàn)需要的安裝包。
??????? 此外我們可以直接在虛擬機(jī)中下載解壓該文件,操作如下:
??????? 首先在虛擬機(jī)中進(jìn)入此次實(shí)驗(yàn)的文件路徑,才相應(yīng)的文件夾下,輸入命令
??????? $ wget https://seedsecuritylabs.org/Labs_20.04/Files/Web_SQL_injection/Labsetup.zip
--no-check-certificate。正常運(yùn)行通過后,即下載完成,而后在該目錄下進(jìn)行解壓縮即可。解壓縮之后,我們通過相對(duì)應(yīng)的容器命令對(duì)容器進(jìn)行設(shè)置。容器的設(shè)置及命令如下所述。
容器設(shè)置和命令
????????在下面,我們列出了一些常用的Docker和Compose命令寫。由于我們將非常頻繁地使用這些命令,所以我們?cè)?bashrc 文件中為他們創(chuàng)建了別名。
$ docker-compose build # Build the container image
$ docker-compose up # Start the container
$ docker-compose down # Shut down the container
// Aliases for the Compose commands above
$ dcbuild # Alias for: docker-compose build
$ dcup # Alias for: docker-compose up
$ dcdown # Alias for: docker-compose down
????????所有的容器都將在后臺(tái)運(yùn)行。要在容器上運(yùn)行命令,我們通常需要在容器上獲得一個(gè)shell。我們首先需要使用“docker ps”命令來找出容器的 ID,然后使用“ docker exec “在該容器上啟動(dòng)shell。同樣。我們?cè)?.bashrc文件中為這些命令創(chuàng)建了別名。
$ dockps %%//%% Alias for: docker ps --format "{{.ID}} {{.Names}}"
$ docksh? %%//%% Alias for: docker exec -it? /bin/bash
// The following example shows how to get a shell inside hostC
????????注意:如果docker命令需要容器 ID,則不需要鍵入整個(gè) ID 字符串。輸入前幾個(gè)字符就足夠了,只要它們?cè)谒腥萜髦心軌蛳嗷^(qū)分。通過以上命令,我們首先對(duì)容器進(jìn)行創(chuàng)建:
$dcbuild??? 運(yùn)行結(jié)果如下:
而后我們對(duì)容器進(jìn)行啟動(dòng):
$dcup?? 運(yùn)行結(jié)果如下:
至此,我們的docker容器已經(jīng)創(chuàng)建并且成功啟動(dòng),其中包含了此次實(shí)驗(yàn)所需要的數(shù)據(jù)庫(kù)的加載和生成相關(guān)信息。
同時(shí),我們根據(jù)壓縮文件中的相關(guān)信息可以知道,我們已經(jīng)為這個(gè)實(shí)驗(yàn)開發(fā)了一個(gè)網(wǎng)絡(luò)應(yīng)用程序,并使用容器來設(shè)置這個(gè)網(wǎng)絡(luò)應(yīng)用程序。實(shí)驗(yàn)設(shè)置中有兩個(gè)容器,一個(gè)用于托管 Web 應(yīng)用程序,另一個(gè)用于托管 Web 應(yīng)用程序依賴的數(shù)據(jù)庫(kù)。Web 應(yīng)用程序容器的 IP 地址為 10.9.0.5,Web應(yīng)用程序的?URL?如下:
http://www.seed-server.com
我們需要將此主機(jī)名映射到容器的IP地址。請(qǐng)將以下條目添加到 /etc/hosts 文件中。您需要使用root特權(quán)來更改此文件(使用sudo)。需要注意的是,由于其他一些實(shí)驗(yàn),此名稱可能已添加到文件中。如果映射到不同的 IP 地址,則必須刪除舊條目。
10.9.0.5???? www.seed-server.com
?????? 最后一行中我們添加上我們需要的映射即可
MySQL數(shù)據(jù)庫(kù)
容器通常是一次性的,因此一旦被銷毀,容器內(nèi)的所有數(shù)據(jù)都會(huì)丟失。對(duì)于此次實(shí)驗(yàn),我們確實(shí)希望將數(shù)據(jù)保留在 MySQL 數(shù)據(jù)庫(kù)中,確保我們?cè)陉P(guān)閉容器時(shí),我們不會(huì)丟失工作。為此,我們將主機(jī)上的mysql_data文件夾(在 MySQL 容器運(yùn)行后,在Labsetup文件夾內(nèi)創(chuàng)建)裝載(mounted)到MySQL容器內(nèi)的 /var/lib/mysql 文件夾中。mysql_data文件夾是 MySQL 存儲(chǔ)其數(shù)據(jù)庫(kù)的地方。因此,即使容器被銷毀,數(shù)據(jù)庫(kù)中的數(shù)據(jù)仍保留。如果我們確實(shí)想從純凈的數(shù)據(jù)庫(kù)開始,可以刪除此文件夾:
$ sudo rm -rf mysql_data
關(guān)于 Web 應(yīng)用程序
我們創(chuàng)建了一個(gè) Web 應(yīng)用程序,這是一個(gè)簡(jiǎn)單的員工管理應(yīng)用程序。員工可以通過此Web應(yīng)用程序查看和更新數(shù)據(jù)庫(kù)中的個(gè)人信息。此Web應(yīng)用程序主要有兩個(gè)角色:Administrator是一個(gè)特權(quán)角色,可以管理每個(gè)員工的個(gè)人資料信息:Employee是一個(gè)正常的角色,可以查看或更新自己的個(gè)人資料信息。表1中描述了所有員工信息。
Table 1: Database
Name |
Employee ID |
Password |
Salary |
Birthday |
SSN |
Nickname |
|
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 |
|
三、實(shí)驗(yàn)內(nèi)容
任務(wù) 1: 熟悉 SQL 語句
任務(wù) 2: 基于SELECT語句的SQL注入攻擊
任務(wù) 3: 基于UPDATE語句的 SQL 注入攻擊
任務(wù) 4: 對(duì)策—Prepared 語句
四、實(shí)驗(yàn)步驟
任務(wù) 1: 熟悉SQL語句
??????? 此任務(wù)的目標(biāo)是通過使用提供的數(shù)據(jù)庫(kù)來熟悉 SQL 命令。我們的 Web 應(yīng)用程序使用的數(shù)據(jù)存儲(chǔ)在 MySQL 數(shù)據(jù)庫(kù)中,該數(shù)據(jù)庫(kù)托管在我們的 MySQL 容器中。我們已經(jīng)創(chuàng)建了一個(gè)名為sqllab_users的數(shù)據(jù)庫(kù),其中包含一個(gè)名為credential的表。該表存儲(chǔ)每個(gè)員工的個(gè)人信息(例如,eid, password, salary, ssn等)。在這項(xiàng)任務(wù)中,您需要使用數(shù)據(jù)庫(kù)來熟悉 SQL 查詢。請(qǐng)?jiān)?/strong> MySQL 容器上獲取shell(請(qǐng)參閱容器說明;手冊(cè)鏈接到實(shí)驗(yàn)的網(wǎng)站)。然后使用 mysql 客戶端程序與數(shù)據(jù)庫(kù)進(jìn)行交互。用戶名是root,密碼是 dees。
// Inside the MySQL container
# mysql -u root -pdees
可知此時(shí)我們開啟容器,并且進(jìn)入數(shù)據(jù)庫(kù)容器,運(yùn)行SQL命令后即可進(jìn)入數(shù)據(jù)庫(kù)。登錄后,我們可以創(chuàng)建新的數(shù)據(jù)庫(kù)或加載現(xiàn)有數(shù)據(jù)庫(kù)。由于我們已經(jīng)利用labsetup壓縮文件中創(chuàng)建的sqllab_users數(shù)據(jù)庫(kù),因此只需要使用使用命令加載此現(xiàn)有數(shù)據(jù)庫(kù)。要顯示sqllab_users數(shù)據(jù)庫(kù)中存在哪些表,您可以使用顯示表命令打印出選定數(shù)據(jù)庫(kù)的所有表。后續(xù)的操作可以進(jìn)一步使我們熟悉SQL的相關(guān)語句。
mysql> use sqllab_users;?? //使用數(shù)據(jù)庫(kù)
Database changed
mysql> show tables;?????? //展示數(shù)據(jù)庫(kù)中的表信息
+------------------------+
| Tables_in_sqllab_users |
+------------------------+
| credential |
+------------------------+
??????? 運(yùn)行上述命令后,您需要使用 SQL 命令打印員工 Alice 的所有個(gè)人資料信息。截圖如下:
任務(wù) 2: 基于SELECT語句的SQL注入攻擊
??????? SQL 注入是一種基本攻擊技術(shù),攻擊者可以通過該技術(shù)執(zhí)行自己的惡意 SQL 語句(通常稱為惡意payload有效載荷)。通過惡意 SQL 語句,攻擊者可以從受害者數(shù)據(jù)庫(kù)竊取信息:更糟的是,他們也許能夠?qū)?shù)據(jù)庫(kù)進(jìn)行更改。我們的員工管理 Web 應(yīng)用程序具有 SQL 注入漏洞,它模仿了開發(fā)人員經(jīng)常犯的錯(cuò)誤。
??????? 我們將使用?www.seed-server.com?的登錄頁面執(zhí)行此任務(wù)。登錄頁面顯示在圖 1 中。它要求用戶提供用戶名和密碼。Web 應(yīng)用程序根據(jù)這兩個(gè)數(shù)據(jù)對(duì)用戶進(jìn)行身份驗(yàn)證,因此只有知道密碼的員工才能登錄。作為攻擊者,我們的工作是在不知道任何員工憑據(jù)的情況下登錄 Web 應(yīng)用程序。登錄界面如下:
??????? 我們首先了解如何在 Web 應(yīng)用程序中實(shí)現(xiàn)身份驗(yàn)證。PHP 代碼unsafe home.php位于/var/www/SQL_Injection 目錄中,用于進(jìn)行用戶身份驗(yàn)證。以下代碼片段顯示用戶如何進(jìn)行身份驗(yàn)證。
$input_uname = $_GET[’username’];
$input_pwd = $_GET[’Password’];
$hashed_pwd = sha1($input_pwd);
...
$sql = "SELECT id, name, eid, salary, birth, ssn, address, email,nickname, Password FROM credential
WHERE name= ’$input_uname’ and Password=’$hashed_pwd’";
$result = $conn -> query($sql);
%%//%% The following is Pseudo Code
if(id != NULL) {
if(name==’admin’) {
return All employees information;
} else if (name !=NULL){
return employee information;
}
} else {
Authentication Fails;
}
??????? 上述 SQL 語句從credential表中選擇員工個(gè)人信息,如 ID、姓名、工資、ssn等。
SQL 語句使用兩個(gè)輸入變量input_uname和hashed_pwd,其中input_uname是在登錄頁面的用戶名字段中鍵入的字符串,而hashed_pwd則保存用戶鍵入的密碼的sha1哈希值。程序檢查任何記錄是否與所提供的用戶名和密碼匹配;如果匹配,用戶將成功進(jìn)行身份驗(yàn)證,并獲得相應(yīng)的員工信息。如果沒有匹配,則身份驗(yàn)證將失敗。
??????? 任務(wù) 2.1:來自網(wǎng)頁的 SQL 注入攻擊。
??????? 我們的任務(wù)是從登錄頁面以管理員的身份登錄 Web 應(yīng)用程序,以便可以查看所有員工的信息。我們假設(shè)確實(shí)知道管理員的帳戶名稱是admin,但不知道密碼。此時(shí),我們需要決定在用戶名和密碼字段中鍵入什么才能在攻擊中取得成功。
??????? 我們通過分析登錄界面的相關(guān)代碼可以知道,其中的SQL語句存在登錄的漏洞,我們通過輸入一直的用戶名,構(gòu)造一個(gè)偽SQL語句即可登錄,展示如上。
??????? 任務(wù) 2.2:從命令行進(jìn)行 SQL 注入攻擊。
????? 此時(shí)的任務(wù)是重復(fù)任務(wù) 2.1,但需要在不使用網(wǎng)頁的情況下執(zhí)行此任務(wù)。我們可以使用命令行工具,如curl,它可以發(fā)送 HTTP 請(qǐng)求。值得一提的是,如果要在 HTTP 請(qǐng)求中包含多個(gè)參數(shù),則需要將?URL?和參數(shù)放在一對(duì)單引號(hào)之間;否則,用于分離參數(shù)(& )的特殊字符將由shell程序解釋,從而更改命令的含義。下列示例顯示了如何向我們的 Web 應(yīng)用程序發(fā)送 HTTP GET 請(qǐng)求,并附加了兩個(gè)參數(shù)(用戶名和密碼):
$ curl ‘www.seed-server.com/unsafe_home.php?username=alice&Password=seedalice’
??????? 如果需要在用戶名或密碼字段中包含特殊字符,則需要正確編碼它們,或者它們可能更改請(qǐng)求的含義。如果想在這些字段包含單引號(hào),我們應(yīng)該用%27代替:如果想包括空格,我們應(yīng)該使用%20。在這項(xiàng)任務(wù)中,當(dāng)使用curl發(fā)送請(qǐng)求時(shí),我們確實(shí)需要處理 HTTP 編碼。
??????? 由上圖,我們可以看出,通過命令行的方式,我們也能夠訪問到我們的目標(biāo)網(wǎng)頁,通過對(duì)圖中標(biāo)記的代碼段進(jìn)行解析,我們可以得到相應(yīng)的數(shù)據(jù)信息。但是此時(shí)我們需要注意的是需要講1中的“’”“#”轉(zhuǎn)換成%27和%23以及將其中的空格轉(zhuǎn)換成“+”。
??????? 任務(wù) 2.3:附加新的 SQL 語句。
??????? 在上述兩次攻擊中,我們只能從數(shù)據(jù)庫(kù)中竊取信息;如果我們能夠使用登錄頁面中的相同漏洞修改數(shù)據(jù)庫(kù),情況會(huì)更好。一種想法是使用 SQL 注入攻擊將一個(gè) SQL 語句變成兩個(gè),第二個(gè)是更新或刪除語句。在 SQL 中,分號(hào)(;)用于分離兩個(gè) SQL 語句。請(qǐng)嘗試通過登錄頁面運(yùn)行兩個(gè) SQL 語句。
??????? 通過登錄界面實(shí)現(xiàn)兩個(gè)SQL語句登錄:由圖可知登錄失敗
通過curl的方式,我們?cè)诿钚羞M(jìn)行訪問時(shí),得到的結(jié)果是一樣的,也就是說,在MySQL數(shù)據(jù)庫(kù)中是無法利用兩個(gè)SQL語句進(jìn)行對(duì)漏洞的攻擊和訪問的。
任務(wù) 3:基于UPDATE語句的 SQL 注入攻擊
??????? 如果 SQL 注入漏洞發(fā)生在 UPDATE 聲明中,則損壞將更為嚴(yán)重,因?yàn)楣粽呖梢允褂迷撀┒葱薷臄?shù)據(jù)庫(kù)。在我們的員工管理應(yīng)用程序中,有一個(gè)編輯配置文件頁面(圖 2),允許員工更新其個(gè)人資料信息,包括昵稱、電子郵件、地址、電話號(hào)碼和密碼。要訪問此頁面,員工需要首先登錄。
??????? 當(dāng)員工通過編輯配置文件頁面更新其信息時(shí),將執(zhí)行以下SQL UPDATE查詢。Unsafe_edit_backend.php代碼文件用于更新員工的個(gè)人資料信息,該P(yáng)HP 文件位于 /var/www/SQLInjection目錄中。
$hashed_pwd = sha1($input_pwd);
$sql = "UPDATE credential SET
nickname=’$input_nickname’,
email=’$input_email’,
address=’$input_address’,
Password=’$hashed_pwd’,
PhoneNumber=’$input_phonenumber’
WHERE ID=$id;";
$conn->query($sql);
任務(wù)3.1:修改自己的工資。
??????? 如編輯配置文件頁面所示,員工只能更新昵稱、電子郵件、地址、電話號(hào)碼和密碼;他們無權(quán)更改工資。假設(shè)我們是員工Alice,而你的老板Boby今年沒有增加你的薪水。我們希望通過利用編輯配置文件頁面中的 SQL 注入漏洞來增加自己的工資。并且我們知道工資在SQL語句中存儲(chǔ)在字段名為salary中。
??????? 由上面所得到的代碼段落分析,我們通過下圖中的操作,即可利用該系統(tǒng)中的SQL漏洞進(jìn)行修改個(gè)人的工資。
工資修改之前的個(gè)人各項(xiàng)數(shù)據(jù)情況,分別是個(gè)人主頁面和Edit Profile頁面的情況:
由上文的代碼塊我們可知,最終提交的字段為Phone Number,所以我們?cè)谳斎霑r(shí)通過更改在Phone Number中的數(shù)據(jù)內(nèi)容,來完成我們對(duì)個(gè)人工資信息的更改,輸入語句如下:
??????? ???????????????? Phonenumber’,salary=’修改工資 ?(標(biāo)點(diǎn)均為英文)
通過上述操作后,我們?cè)诖瞬榭醋约簜€(gè)人的信息,可以看到已經(jīng)修改了個(gè)人的工資以及其他的各項(xiàng)信息:
???????
任務(wù)3.2:修改他人工資。
??????? 由上操作,我們可知曉,可以通過更改相關(guān)的字段來更改自己個(gè)人的工資,下面我們將利用相同的原理對(duì)Boby的工資進(jìn)行修改(目標(biāo)為將工資修改為1)。
??????? Password=’$hashed_pwd’,
??????? PhoneNumber=’$input_phonenumber’
??????? WHERE ID=$id;";
??????? 這幾行代碼我們可以知道,最終提交哦SQL語句時(shí)是通過ID進(jìn)行區(qū)別人員的,所以我們還是和任務(wù)3.1一樣,在Phone Number中進(jìn)行操作,入的代碼如下:
??????? Phonenumber’,salary=’1’ where name=’Boby’;#
截圖展示如下:
?????? 過此番操作后,我們可以通過登錄管理員的賬號(hào)進(jìn)行查詢,以驗(yàn)證我們的操作是否生效,查詢結(jié)果如下圖所展示:
?????? 過查詢,我們可以看到已經(jīng)將Boby的工資修改為“1”。
任務(wù)3.3:修改他人密碼。?
?????? 由3.2我們已經(jīng)對(duì)Boby的薪資進(jìn)行了修改,下一步我們希望能夠通過類似的方式,利用sql語句中的漏洞,將Boby 的賬戶密碼修改為我們知曉的,從而我們可以登錄其賬戶進(jìn)行進(jìn)一步的操作。此時(shí),我們知道了上述的相應(yīng)代碼塊以及知曉數(shù)據(jù)庫(kù)存儲(chǔ)了密碼的哈希值,而不是簡(jiǎn)單的密碼字符串并且它使用了SHA1 哈希功能生成密碼的哈希值。下面我們將嘗試是否能夠更改Boby的賬戶密碼。
??????? 此過程中我們將通過修改Phone number中的語句來修改Boby的密碼,語句如下:
??????? 123456',Password=sha1('alice11') where name='Boby';#
??????? 通過上述的修改后,我們通過登錄Boby的賬戶進(jìn)行驗(yàn)證是否修改成功,我們將先輸入原始密碼:seedboby,通過登錄發(fā)現(xiàn)密碼錯(cuò)誤無法登錄。:
??????? 接下來我們將輸入自己修改后的密碼進(jìn)行登錄驗(yàn)證:
??????? 此時(shí)我們發(fā)現(xiàn),登錄成功,證明我們對(duì)Boby的密碼修改成功。
五、實(shí)驗(yàn)結(jié)果及分析
??????? 此次實(shí)驗(yàn),我們通過多項(xiàng)操作能夠?qū)崿F(xiàn)對(duì)一個(gè)簡(jiǎn)單編寫的前端頁面和數(shù)據(jù)庫(kù)的SQL注入攻擊,實(shí)驗(yàn)過程中我們通過不同的方法實(shí)現(xiàn)了對(duì)用戶信息以及用戶賬戶信息的更改和侵入。此外,我們通過對(duì)源代碼的分析,基本上實(shí)現(xiàn)了簡(jiǎn)單SQL注入攻擊的防御,但是相對(duì)而言還有更多的問題亟待解決,不過就整體而言,初步達(dá)到了實(shí)驗(yàn)的預(yù)期目標(biāo)。文章來源:http://www.zghlxwxcb.cn/news/detail-848415.html
六、總結(jié)
????????通過此次實(shí)驗(yàn),我們利用SQL注入的方法實(shí)現(xiàn)了相關(guān)的簡(jiǎn)易攻擊,進(jìn)一步理解了數(shù)據(jù)庫(kù)漏洞的危害性,同時(shí)明白了web開發(fā)過程中嚴(yán)謹(jǐn)性的重要性,熟悉了web開發(fā)中開發(fā)人員常犯的常規(guī)錯(cuò)誤,使得我們更加清晰的認(rèn)識(shí)了SQL注入攻擊帶來的損害。文章來源地址http://www.zghlxwxcb.cn/news/detail-848415.html
到了這里,關(guān)于網(wǎng)絡(luò)安全---SQL注入攻擊的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!