二次注入詳解


0x01 前言

前幾天看一些面經的時候,看到sql注入的二次注入,當時沒一下子反應過來,好家伙,趕緊再次去那個靶場sqli-labs/Less24復現一下二次注入。

0x02 什么是二次注入?

二次注入可以理解為,攻擊者構造的惡意數據存儲在數據庫后,惡意數據被讀取並進入到SQL查詢語句所導致的注入。防御者即使對用戶輸入的惡意數據進行轉義,當數據插入到數據庫中時被處理的數據又被還原,Web程序調用存儲在數據庫中的惡意數據並執行SQL查詢時,就發生了SQL二次注入。

也就是說一次攻擊造成不了什么,但是兩次配合起來就會早成注入漏洞。

0x03 注入條件

兩次注入分別是插入惡意數據利用惡意數據

所以也就是滿足這兩個條件即可

  • 用戶向數據庫插入惡意數據,即使后端對語句做了轉義,如mysql_escape_string、mysql_real_escape_string等函數
  • 數據庫能夠將惡意數據取出

0x04 靶場實例

首先進入靶場,可以看到與其他靶場不同,這里多了忘記密碼和注冊密碼選項

img

嘗試常規post注入,未果。

image-20220409195347007

這里看到后端源碼會發現使用了轉義函數mysql_real_escape_string,常規SQL注入流程無法走了

既然可以注冊賬戶那就去注冊一下,這里直接注冊admin'#

image-20220409200822312

用注冊的賬號登錄進去后發現可以修改密碼

image-20220409201032225

修改密碼這個模塊也可以利用,我們不妨想一下修改密碼后端實現的邏輯,使用的肯定是sql增刪改查中的改語句,於是猜想對應sql語句可能會是這樣

update users set password='$new_pass' where username='$user' and password='$old_pass';

(當然閉合方式不一定就是單引號,這里需要碰運氣吧。。)

如果我們注冊一個這樣的賬號 admin'# 上述sql語句就變成這樣

update users set password='$new_pass' where username='admin'# and password='$old_pass';

顯而易見,語句原義被破壞,本來修改的是admin'# 用戶的賬號和密碼,現在卻是變成了直接修改admin用戶的密碼!

那就隨便輸入個密碼123456修改后再拿它去嘗試登錄admin賬戶,發現成功登入。

image-20220409201506816

image-20220409201550144

image-20220409201620226

說明數據庫中admin用戶的密碼已經被成功改為123456

0x05 如何防御二次注入?

  • 對輸入一視同仁,無論輸入來自用戶還是存儲,在進入到 SQL 查詢前都對其進行過濾、轉義。
  • 使用MySQLi參數化更新,事先編譯的PHP代碼能夠帶來高效的防護效果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM