一、Sql注入
sql注入漏洞的成因是由于后端數據庫查詢語句沒有做過濾導致了前端輸入字符串可以直接拼接到語句而獲取數據庫信息。
1.類型
數字型和字符型
區分:數字型可以進行加減運算,id=1+1會獲取id=2的信息,而字符型只會獲取1的數據
2.方法
(1)聯合查詢
使用union select 聯合查詢,通過mysql的information_schema數據庫中的columns表和tables表獲取
#使用聯合查詢之前要使用order by看看數據的列數,再聯合查詢相應的列數
#此時假設有3列數據,聯合查詢先用1,2,3看看頁面回顯是哪個數據1還是2還是3的位置
union select 1,2,3;
#知道數據回顯位置,比如2,3在頁面某個位置出現回顯,那么就可以再2或者3上進行數據查詢,從而回顯到頁面,先查詢數據庫獲取當前數據庫
union select 1,database(),3
#獲取數據庫名后應該需要獲取表名 如何獲取?
#mysql數據庫存在一個information_schema數據庫,有所有的數據庫,表,字段名的信息,可以通過這個已知的數據庫以及已知的表都存放在tables表里來進行查詢,否則你不知道當前數據庫的表有哪些,也無法查詢。
union select 1,group_concat(table_name) from information_schema.tables where table_schema="當前數據庫名",3;
#獲取表名以后,就要看看這個表里都有什么字段名,可以通過columns表
union select 1,group_concat(column_name) from information_schema.columns where table_schema="當前數據庫名" and table_name="想查詢表名",3;
#知道了數據庫名表名和字段名就可以直接通過select語句進行查詢
union select [字段名] from 數據庫.表名
(2)報錯注入
使用函數extractvalue()函數,由于有些函數的優先級高,會優先執行函數里的內容再返回,使用該函數來實現報錯,然后利用concat來進行語句的查詢。先執行函數里的內容然后使用concat來執行
extractvalue():函數只有兩個參數
extractvalue(xml_document, xpath_string) 通常sql報錯注入的語句放在第二個參數位置,因為第一個參數是xml文檔,不是合法 XML就會報錯,也會執行語句但是局限較大。第二個參數使用concat可以進行拼接等操作,靈活性比較大
#爆破數據庫,concat輸入特殊字符報錯,使用database查詢,查詢語句同聯合查詢類似。
select extractvalue(1,concat(~,database(),~))#注意點:這個函數以及updatexml函數都最多返回32個字符多余的會被截斷,因此會采用截取子字符串的方法最后拼接來獲取整個數據信息
#用法如下:
select extractvalue(1,concat(~,substr(database(),1,32),~))
(3)布爾盲注
連接符使用and
substr(str, pos, len)
str:要截取的字符串
pos:起始位置(從 1 開始計數,不是 0!)
len:截取的長度(可省略,如果省略則取到末尾)
利用了頁面注入正確有回顯,注入錯誤無回顯,來判斷注入情況,獲取信息,因此可以單個字符判斷
#1.獲取數據庫長度使用length()一個個試
length(database())=n;
#2.猜數據庫名,有回顯說明ascii值對應的字母是正確的,再猜測下一個
ascii(substr(database(),1,1))= [ascii值]
(4)延時盲注
sleep():使用sleep函數來讓頁面延遲響應通過響應時間判斷正確與否
if(ascii(substr((database()), i, 1)) = N, SLEEP(5), 0)
(5)寬字節注入
由于后端使用轉義字符導致的寬字節注入,即使用gbk編碼,將轉義字符與一個大于255的編碼組合起來會自動當作gbk編碼為一個漢字或其他語言的字,即需要兩個字節,相當于把后端帶的轉義字符與注入的合并起來導致轉義字符無效。
#吞掉后使用聯合查詢一樣正常查詢
id=-1 %df' union select 1,2,3 --+
(6)堆疊注入
堆疊注入即有些數據庫支持多條語句輸入,即可以使用分號結束語句并在后面執行其他語句也可以成功執行。
1'; insert into [表名] value(值);
(7)二次注入
由于數據庫對已經確認過的數據過于信任沒有進行二次驗證導致出現了二次注入的漏洞
比如創建了一個admin’#用戶 而數據庫已經存在admin用戶,那么再修改密碼時沒有驗證用戶身份而是直接找到這個用戶進行修改,修改過程中’#有其他特殊含義,導致后面的原始密碼被注釋可以直接修改密碼且修改的密碼用戶是admin,因為’#有特殊含義
3.防御
(1)使用預編譯/參數化查詢
把sql語句和數據分開處理,避免拼接。
預編譯:即先告訴數據庫這條 SQL 的“結構”(有兩個 ?
占位符)。數據庫編譯并優化語句結構。再把參數安全地綁定進去。
**PHP (PDO):**是 PHP 提供的數據庫訪問抽象層。
支持 預編譯,防 SQL 注入。
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
**Java (JDBC):**是 Java 的數據庫連接 API,用于操作各種數據庫。
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username=? AND password=?"
);
stmt.setString(1, username);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
(2)使用Web應用防火墻(WAF)
對常見的sql注入payload進行攔截
二、XSS漏洞
1.類型
(1)反射型
經過服務器未經過濾直接返回到頁面。一次性的
出現位置:搜索框
(2)存儲型
上傳存儲到數據庫,每次訪問的時候都會加載,由于數據庫沒對前端輸入的代碼進行過濾
出現位置:留言板,評論區
(3)DOM型
沒有經過服務器直接在前端執行,JS 直接拼接用戶輸入進 DOM。
出現位置:前端 JS 對 DOM 的處理
2.繞過方法
1.直接注入
<script>alert(/1/)</script>
2.大小寫繞過
可能黑名單限制了script一些相關字符的輸入,但是卻忘記忽略大小寫,因此可以嘗試將關鍵字大小寫修改嘗試
<Script>alert(/1/)</Script>
3.雙寫繞過
可能對字符串進行過濾,但是替換為空字符而不是下劃線之類的符號,導致可以使用雙寫繞過
<Scrscriptipt>alert(/1/)</Scscriptript>
4.img標簽報錯繞過
讓img標簽報錯,報錯時執行, 因此可以手動設置錯誤的圖片路徑導致報錯響應
<img src=1 onerror='alert(1)'>
5.閉合標簽繞過
如果使用了input標簽可以嘗試使用閉合繞過,不過要查看源碼看看閉合方式
<--最簡單的一種,也可以使用閉合+img/a/偽協議/大小寫/雙寫 結合繞過 !-->
'> <script>alert(/1/)</script>
6.onclick繞過
input標簽,可以使用閉合+onclick,實現點擊彈窗,不用
' onclick='alert(1) <-后面應該有原有的閉合->
7.a標簽偽協議繞過
JavaScript偽協議繞過,比如識別<script但是沒有識別javascript時可以使用偽協議繞過
<a href=javascript: alert('1')>
8.a標簽編碼特殊繞過方式
有a標簽存在時,可以用實體編碼繞過,因為a標簽的特殊性:可以將實體編碼上傳到數據庫在點擊標簽時才進行解析并且會自動將編碼解析
javascript:alert('1') #將sc使用實體編碼編碼
3.防御方法
1.黑名單限制
限制關鍵字,script,on,error
2.白名單限制
只允許一些類型通過
3.忽略大小寫
使用strtolower同一轉換為小寫
4.使用編碼
將所有輸入的內容當作文本顯示,沒有特殊含義
三、文件上傳漏洞
1.繞過方式
1.大小寫繞過
后綴有黑名單限制但是忘記忽略大小寫
.pHp .PHP .PhP .PHp
2.雙寫繞過
由于將匹配的字符串轉為空字符,因此可以使用雙寫繞過
.ph(php)p #將括號中的php匹配成功替換為空字符了
3.php3,phtml繞過
php無法使用但是可能沒有禁止php3后綴,所以可以使用備用類型繞過
.php3
4.空格繞過
首尾空格字符在文件中最后解析會把空格自動清掉,但是輸入空格可能不會被過濾,從而繞過
.php
5.mime類型繞過
瀏覽器會讀取文件的 擴展名 / 系統注冊信息,然后決定 MIME
可以抓包看到一個content-type字段,后端僅驗證content-type,因此可以直接修改數據包為需要的類型然后上傳
6.前端繞過
前端進行驗證,可以直接將前端的驗證代碼刪除或者修改.
7. .htaccess區域解析配置文件繞過
由于限制了大多數類型文件,但是沒有限制這個特殊文件.htaccess類型,這個文件配置后會解析同目錄下的文件為設置的類型
1.解析所有文件為php:
SetHandler
SetHandler application/x-httpd-php
2.指定后綴名解析為php: AddHandler
指定的后綴名用空格隔開放在最后
AddHandler application/x-httpd-php .php .phtml .html
8. 00截斷繞過
00截斷,在文件名后加一個可以通過的類型使用%00連接,解析時會把00后面的內容刪掉,也就是解析hello.php按照php類型解析
file=hello.php%00.jpg
2.防御方法
1.使用strtolower函數防止大小寫
2.使用白名單限制
3.使用waf限制
四、CSRF和SSRF
1.CSRF(跨站請求偽造)
- 與XSS的區別
CSRF是跨站請求偽造。它偽造了用戶的請求,并不是用戶的真實意愿,而是通過誘導用戶點擊一些惡意鏈接使用用戶的cookie信息等去執行一些用戶并沒有想執行的操作。
XSS是跨站腳本攻擊。在用戶瀏覽器執行惡意代碼,直接竊取數據或劫持用戶。
二者本質區別 csrf是在用戶登陸的前提下使用用戶的cookie信息執行一些轉賬或者發信息、修改信息其他的類似操作。而xss是用來竊取用戶的cookie信息,只需要用戶點擊
- CSRF的應用場景
修改密碼,轉賬,修改個人信息等操作
- CSRF漏洞利用
抓取數據包,找到表單信息,修改表單信息提交到服務器看看是否成功,成功則說明存在CSRF漏洞
- 成因
Web 應用只依賴 Cookie / Session 里的認證信息來識別用戶身份,而沒有驗證請求本身的來源和合法性
2.SSRF(服務器端跨站請求偽造)
- 成因
由于服務器提供了從其他服務器獲取數據的功能,比如翻譯的軟件,可以自動從其他服務器下載并獲取數據。
比如從翻譯軟件翻譯一個查ip的網頁,會發現ip不是本機的,實際可能是服務器的,因為這個加載過程是服務器完成的。
3.CSRF與SSRF的區別
最大的區別就是
CSRF是客戶端的,也就是用戶受騙,“莫名不自覺”執行了自己沒想執行的操作
SSRF是服務器端的,也就是服務器受騙,按著攻擊者的想法執行一些危險操作。
五、文件包含和文件讀取漏洞
1.區別
文件包含漏洞可以解析文件執行文件,而文件讀取只會對文件的內容進行讀取,不進行解析。
2.示例
文件讀取,無法解析phpinfo文件,頁面空白,看源碼可以看到
<?php$file=$_GET['file'];
echo fgets(fopen($file,"r"));?>
且源碼寫了多行也只看的見一行.
同一個文件,使用文件包含可以執行解析.
<?php$file=$_GET['file'];
echo include $file;?>
行文件,而文件讀取只會對文件的內容進行讀取,不進行解析。
2.示例
文件讀取,無法解析phpinfo文件,頁面空白,看源碼可以看到
<?php$file=$_GET['file'];
echo fgets(fopen($file,"r"));?>
[外鏈圖片轉存中…(img-l96bh0Un-1756297342382)]
且源碼寫了多行也只看的見一行.
[外鏈圖片轉存中…(img-SGRDaUnS-1756297342383)]
同一個文件,使用文件包含可以執行解析.
<?php$file=$_GET['file'];
echo include $file;?>
[外鏈圖片轉存中…(img-ffHaA7Pl-1756297342383)]