靶場:NSSCTF 、云曦歷年考核題
二、sql注入
NSSCTF
【SWPUCTF 2021 新生賽】easy_sql
這題雖然之前做過,但為了學習sql,整理一下就再寫一次
打開以后是杰哥的界面
注意到html網頁標題的名稱是? “參數是wllm”
那就傳參數值試一試
首先判斷注入類型(數字型或字符型)
傳1
傳2 沒有回顯
同樣的,后面的3456都沒有回顯
光傳abc也沒有回顯
所以應該是數字型注入
然后判斷閉合方式
接下來傳1'?? (單引號)
出現報錯
然后傳1" ? (雙引號)
頁面又有回顯??
回到報錯的 1'頁面,分析報錯語句
注意看這個位置
這里要記住的是:無論是單引號還是雙引號在sql語句中都是成對出現的,包括 ( ) { } 【】各種括號 。
所以上面的報錯句應該注意到最后的一個引號,要成對則前面必有一個單引號與它成一對。
也就是說,在這個報錯語句中,一對單引號 ' ' 包裹著剛才我們注入的內容:' 1' '
所以這一堆引號就該這么拆:
'?? '? 1'? ' LIMIT 0,1? '
所以包裹著我們注入的 1' 的就是單引號? ' ' 。也就是說明這題的閉合方式是單引號。
既然如此那加個注釋: --+???
目的是把單引號注釋掉
發現頁面沒有報錯了,有了回顯,這就說明閉合方式判斷正確
這里還有一個驗證是否存在sql漏洞的方法:
當輸入1=1時(條件為真),頁面正常顯示或有回顯
?
當輸入1=2時(條件為假),頁面未正常顯示
?這就說明我們輸入的內容數據庫是能夠執行的,即存在sql注入漏洞
那么接下來就是一系列的爆數據庫,直到爆出需要的信息(flag)
正規的講叫先判斷列數
語句是order by
比如現在一列列爆
第一列,有
?第二列有
第三列也有
但是到了第三列就會顯示它不認識了
包括后面的第5列也如此
也就是說,這個數據庫里的表總的只有三列
既然查出了總列數,接下來就需要聯合查詢所有列數下的數據,語句 union select
這里要注意:需要把傳入參數的值1改為-1
然后開始聯合查詢
可以看到用戶名位于第2列的位置,密碼位于第3列的位置 (回顯位為2、3位)
接下來可以看看這兩列的數據,一列列來,第2列:
有了 ,可以看到是test_db
第3列:
都是test_db ,這當然的,兩個都在一個數據庫(test_db)里面
爆出來的這個是數據庫名
接下來查表名(table_name)
然后出現這么個東東
英語也不太好,翻譯一下
ouou? 我知道了,我只改了第2列數據庫名的位置,忘了后面還有個第3列了
大意了haha
加入第3列
提示返回的信息超過一行
一個解決辦法就是使用group_concat把table_name變為一行即可????? group_concat(table_name)
得到有兩個表的表名
接下來查列名(column_name ):
對應的把剛剛的表名table_name改為column_name(列名);
tables改為columns,最后加上剛查到的表名users
執行
select group_concat(column_name) from information_schema.columns where table_schema='test_db' and table_name='users'
得到列名為password
都查出來了,select后面的就全扔掉,看看列名為password的數據列里面有什么,有沒有想要的數據(flag)但這里好像出了點問題,爆出來又是yyy(不對,沒問題,我查的就是password,而password為yyy剛開始就告訴我了),所以問題在于沒有爆出可用的列名
回去找了一下,應該是上一步爆列名的問題,命令
select group_concat(column_name) from information_schema.columns where table_schema='test_db' and table_name='users'
應該改寫為
select group_concat(column_name) from information_schema.columns where table_schema='test_db'
即刪去了后面的and tablename='users'
至于為什么要這么改,后面也想清楚了:
如果查列名的語句含有 and table_name='users'?? 這樣就代表我們是查詢名為users的表下的所有列名;
而如果刪去 and table_name='users'? 僅前面的語句就不指定表名而是查詢所有表下的所有列名,這樣才能把flag列名爆出來? (也就是說其實flag是存在于test_tb表下的,而并不在users表下,如果冒然的將查詢列規定為users表下面,只會畫蛇添足,還找不到flag)
弄清楚以后重新爆列名,不用多此一舉限制查詢的范圍(刪去 and table_name='users')
發現這次列名就全了,可以看到flag列了。
那么接下來直接爆flag
既然剛剛無意中發現flag不在users表下而是在test_tb表下,那就直接爆test_tb表的flag列即可
?
?